package com.imdroid.sideslope.server;

import io.netty.channel.Channel;

import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author Layton
 * @date 2023/2/2 21:00
 * 提供两种获取channel的方法：通过deviceId；通过imei。imei是DTU连接服务器最先上报的消息
 * 利用imei-ipaddr-deviceId，可以发现imei和deviceId的绑定关系
 */
public class OnlineChannels {

    public static final OnlineChannels INSTANCE = new OnlineChannels();

    // 设备已连接，deviceId已上报
    private final Map<String, DeviceChannel> dataChannels = new ConcurrentHashMap<>();
    private final Map<String, DeviceChannel> configChannels = new ConcurrentHashMap<>();

    private OnlineChannels() {}

    public DeviceChannel updateDataChannel(String deviceId, Channel channel, InetSocketAddress address) {
        DeviceChannel deviceChannel = dataChannels.get(deviceId);
        if(deviceChannel == null){
            deviceChannel = new DeviceChannel(deviceId, channel, address);
            dataChannels.put(deviceId, deviceChannel);
        }
        else {
            deviceChannel.setChannel(channel);
            deviceChannel.setAddress(address);
        }

        return deviceChannel;
    }

    public DeviceChannel updateConfigChannel(String deviceId, Channel channel, InetSocketAddress address) {
        DeviceChannel deviceChannel = configChannels.get(deviceId);
        if(deviceChannel == null){
            deviceChannel = new DeviceChannel(deviceId, channel, address);
            configChannels.put(deviceId, deviceChannel);
        }
        else {
            deviceChannel.setChannel(channel);
            deviceChannel.setAddress(address);
        }

        return deviceChannel;
    }

    public Optional<DeviceChannel> get(String deviceId) {
        return Optional.ofNullable(dataChannels.get(deviceId));
    }

    public List<DeviceChannel> ifPresent(List<String> deviceIds) {
        return deviceIds.stream().map(x -> dataChannels.get(x)).filter(Objects::nonNull).collect(Collectors.toList());
    }

    public DeviceChannel getDataChannel(String deviceId){
        return dataChannels.get(deviceId);
    }
    public DeviceChannel getConfigChannel(String deviceId){
        return configChannels.get(deviceId);
    }

}
