package com.docus.server.common.netty.server;

import com.docus.server.dto.scheduling.management.schterminator.NettyTerminatorDTO;
import com.docus.server.enums.BusyStateEnum;
import com.docus.server.enums.OnlineStateEnum;
import com.docus.server.service.ISchTerminatorService;
import com.docus.server.vo.scheduling.management.schterminator.SchTerminatorVO;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 客户端IP和通信信道的映射
 */
@Component
@Slf4j
public class TerminalToChannelCacheMap {
    @Resource
    private ISchTerminatorService iSchTerminatorService;

    /**
     * <IP-Channel>
     */
    private final static Map<String, Channel> IP_CHANNEL_CACHE_MAP = new ConcurrentHashMap<>();

    /**
     * <IP-Terminator>
     */
    private final static Map<String, NettyTerminatorDTO> IP_TERMINATOR_CACHE_MAP = new ConcurrentHashMap<>();

    /**
     * 终端上线
     */
    public void put(NettyTerminatorDTO nettyTerminatorDTO, Channel channel) {
        //客户端上线
        String terminatorIp = nettyTerminatorDTO.getTerminatorIp();

        //更新数据库终端数据
        SchTerminatorVO schTerminatorVO = iSchTerminatorService.saveOrUpdate(terminatorIp, nettyTerminatorDTO);
        nettyTerminatorDTO.setId(schTerminatorVO.getId());

        //缓存
        IP_CHANNEL_CACHE_MAP.put(terminatorIp, channel);
        IP_TERMINATOR_CACHE_MAP.put(terminatorIp, nettyTerminatorDTO);

        AttributeKey<String> attributeKey = AttributeKey.valueOf("ip");
        channel.attr(attributeKey).set(terminatorIp);


    }

    public String getClientKey(Channel channel) {

        AttributeKey<String> key = AttributeKey.valueOf("ip");

        if (channel.hasAttr(key)) {
            return channel.attr(key).get();
        }
        return null;
    }

    public Channel get(String key) {
        return IP_CHANNEL_CACHE_MAP.get(key);
    }

    public NettyTerminatorDTO getTerminatorByIp(String key) {
        return IP_TERMINATOR_CACHE_MAP.get(key);
    }

    public Map<String, Channel> getIpToChannelCacheMap() {
        return IP_CHANNEL_CACHE_MAP;
    }

    public Map<String, NettyTerminatorDTO> getIpToTerminatorCacheMap() {
        return IP_TERMINATOR_CACHE_MAP;
    }

    public List<NettyTerminatorDTO> getAvailTerminator() {
        if (!CollectionUtils.isEmpty(IP_TERMINATOR_CACHE_MAP)) {
            return IP_TERMINATOR_CACHE_MAP.values().stream().filter(p -> OnlineStateEnum.ONLINE.equals(p.getOnlineState())
                && BusyStateEnum.IDLE.equals(p.getBusyState())).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    /**
     * 终端离线
     */
    public void remove(String key) {
        IP_CHANNEL_CACHE_MAP.remove(key);
        IP_TERMINATOR_CACHE_MAP.remove(key);
        NettyTerminatorDTO nettyTerminatorDTO = new NettyTerminatorDTO();
        nettyTerminatorDTO.setBusyState(BusyStateEnum.IDLE);
        nettyTerminatorDTO.setOnlineState(OnlineStateEnum.OFFLINE);
        iSchTerminatorService.saveOrUpdate(key, nettyTerminatorDTO);
    }

}
