package com.xueyi.message.transfer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.corundumstudio.socketio.listener.ExceptionListener;
import com.xueyi.common.core.utils.InetAddressUtils;
import com.xueyi.message.api.transfer.domain.vo.Message;
import com.xueyi.message.transfer.service.IMessageQueueService;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class MessageQueueServiceImpl implements IMessageQueueService {

    @Autowired
    RedisTemplate<String, Serializable> redisTemplate;
    private Integer port = 9901;

    private SocketIOServer server;
    private ConcurrentHashMap<String, Message> messageMap = new ConcurrentHashMap<>();

    MessageQueueServiceImpl(){
        startServer(port);
    }

//    @Override
//    public List<Message> getAll(){
//        List<Message> list = new ArrayList<Message>();
//        Iterator<Map.Entry<String, Message>> entries = messageMap.entrySet().iterator();
//        while(entries.hasNext()){
//            Map.Entry<String, Message> entry = entries.next();
//            Message value = entry.getValue();
//            if(System.currentTimeMillis()- value.getTimestamp() > 10000){
//                messageMap.remove(entry.getKey());
//            }else{
//                list.add(value);
//            }
//        }
//        if(list.size()>0){
//            return list;
//        }
//        return null;
//    }
//
//    @Override
//    public boolean add(Message message){
//
//        messageMap.put(message.getVid(),message);
//        return true;
//    }

    @Override
    public void broadcast(String channel, String message){
        server.getBroadcastOperations().sendEvent(channel,message);
    }

    @Override
    public Collection<SocketIOClient> getAllClients(){
        return server.getAllClients();
    }


    private void startServer(int port){
        Configuration config = new Configuration();
        ExceptionListener exceptionListener = new ExceptionListener() {
            @Override
            public void onEventException(Exception e, List<Object> list, SocketIOClient socketIOClient) {

            }

            @Override
            public void onDisconnectException(Exception e, SocketIOClient socketIOClient) {

            }

            @Override
            public void onConnectException(Exception e, SocketIOClient socketIOClient) {

            }

            @Override
            public boolean exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable throwable) throws Exception {
                channelHandlerContext.close();
                return true;
            }
        };
        try {
            System.out.println("启动");
//            config.setHostname(InetAddressUtils.getLocalHostLANAddress().getHostAddress());
            config.setHostname("0.0.0.0");

        } catch (Exception e) {
            e.printStackTrace();
        }
        config.setPort(port);
        config.setExceptionListener(exceptionListener);
        server = new SocketIOServer(config);
        server.addConnectListener(new ConnectListener() {
            // 添加客户端连接监听器
            @Override
            public void onConnect(SocketIOClient client) {
                System.out.println(client.getRemoteAddress().toString());
                if(client.getRemoteAddress().toString().contains("100.117") || client.getRemoteAddress().toString().contains("100.171")){
                    client.disconnect();
                    return;
                }
                client.sendEvent("connected", "hello");
            }
        });

        server.addEventListener("client_info", String.class, new DataListener<String>(){
            @Override
            public void onData(SocketIOClient client, String data, AckRequest ackRequest) throws ClassNotFoundException {
                //客户端推送advert_info事件时，onData接受数据，这里是string类型的json数据，还可以为Byte[],object其他类型
                String sa = client.getRemoteAddress().toString();
                String clientIp = sa.substring(1,sa.indexOf(":"));//获取客户端连接的ip
                Map params = client.getHandshakeData().getUrlParams();//获取客户端url参数
                System.out.println(clientIp+"：客户端：************"+data);
            }
        });
//        server.addEventListener("remove_vinfromrsu", String.class, new DataListener<String>() {
//            @Override
//            public void onData(SocketIOClient socketIOClient, String s, AckRequest ackRequest) throws Exception {
//                System.out.println("remove_vinfromrsu : " + s);
//                List<RsuEventSimulatorMessage> list = JSON.parseArray(s, RsuEventSimulatorMessage.class);
//                for (RsuEventSimulatorMessage item : list) {
//                    for (String vout : item.getVinouts()) {
//                        redisTemplate.opsForSet().remove("rsu_" + item.getRsuId(),vout);
//                    }
//                }
//            }
//        });
//        server.addEventListener("screen_info", String.class, new DataListener<String>(){
//            @Override
//            public void onData(SocketIOClient client, String data, AckRequest ackRequest) throws ClassNotFoundException {
//                VehicleGridCountItem item = ((JSONObject)JSON.parse(data)).toJavaObject(VehicleGridCountItem.class);
//                gridCountItemMap.put(client,item);
//            }
//        });
        //添加客户端断开连接事件
        server.addDisconnectListener(new DisconnectListener(){
            @Override
            public void onDisconnect(SocketIOClient client) {
                String sa = client.getRemoteAddress().toString();
                String clientIp = sa.substring(1,sa.indexOf(":"));//获取设备ip
                System.out.println(clientIp+"-------------------------"+"客户端已断开连接");
                //给客户端发送消息
                client.sendEvent("advert_info",clientIp+"客户端你好，我是服务端，期待下次和你见面");
            }
        });
        server.start();
    }

}
