package com.tsi.comm.server.repository;

import com.tsi.app.common.utils.Counter;
import com.tsi.app.common.xnet.NettyUtils;
import com.tsi.comm.server.vo.TsiNodeVo;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@RequiredArgsConstructor
@Component
public class TsiSessionManager {

    public static final AttributeKey<TsiNodeVo> TSI_NODE_ATTRIBUTE_KEY = AttributeKey.valueOf("TsiNode");
    @Getter
    private volatile boolean serverRun;
    private final Counter sessions = new Counter();
    private final ConcurrentHashMap<Channel, TsiNodeVo> channelNodeMap = new ConcurrentHashMap<>();

    public int add() {
        return (int) this.sessions.increment();
    }
    public int remove() {
        return (int) this.sessions.decrement();
    }
    public int get() {
        return (int) this.sessions.get();
    }

    public void addChannel(Channel channel, TsiNodeVo vo) {
        this.channelNodeMap.put(channel, vo);
    }
    public void removeChannel(Channel channel) {
        this.channelNodeMap.remove(channel);
    }

    public TsiNodeVo getNodeVo(Channel channel) {
        return this.channelNodeMap.get(channel);
    }

    public void start() {
        this.serverRun = true;
    }
    public void stop() {
        this.serverRun = false;
    }

    public void reportChannelSessions() {
        log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        log.info("Report Channel Sessions: {} Sessions.", this.sessions.get());
        log.info("{}", String.format("%10s %7s  Remote-Address", "ID", "Active"));
        log.info("----------------------------------------------------------------------------------------------------------------");
        for (Map.Entry<Channel, TsiNodeVo> obj : this.channelNodeMap.entrySet()) {
            Channel channel = obj.getKey();
            TsiNodeVo node = obj.getValue();
            log.info("{}", String.format("%10s %7s  %s", node.getNodeId(), channel.isActive(), NettyUtils.getRemoteAddress(channel)));
        }
        log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
    }

}
