package com.yfd.platform.component.nettyclient;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yfd.platform.config.ParentConfig;
import com.yfd.platform.constant.Constant;
import com.yfd.platform.constant.SystemCode;
import com.yfd.platform.modules.patroltask.service.ITaskTodoService;
import com.yfd.platform.modules.robotapi.domain.PlatformParentSystem;
import com.yfd.platform.modules.robotapi.service.IPlatformParentSystemService;
import com.yfd.platform.utils.SpringContextHolder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.List;

import static com.yfd.platform.component.nettyclient.BootSessionCache.requestSessionID;

/**
 *

 */
public class BootNettyClient {
    private static final Logger logger = LoggerFactory.getLogger(BootNettyClient.class);


    public void connect(String ServerIP,int Serverport, ParentConfig parentConfig) throws InterruptedException {
        // 获取spring bean
        IPlatformParentSystemService platformParentSystemService = SpringContextHolder.getBean(IPlatformParentSystemService.class);
        HeartBeatTask heartBeatTask = SpringContextHolder.getBean(HeartBeatTask.class);
        /**
         * 客户端的NIO线程组
         *
         */
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            /**
             * Bootstrap 是一个启动NIO服务的辅助启动类 客户端的
             */
            Bootstrap bootstrap = new Bootstrap();
            bootstrap = bootstrap.group(group);
            bootstrap = bootstrap.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true);
            /**
             * 设置 I/O处理类,主要用于网络I/O事件，记录日志，编码、解码消息
             */
            bootstrap = bootstrap.handler(new BootNettyChannelInitializer<SocketChannel>());
            /**
             * 连接服务端
             */
            logger.info("ServerIP"+ServerIP+"Serverport"+Serverport);
            ChannelFuture future = bootstrap.connect(ServerIP, Serverport).sync();
            if(future.isSuccess()) {
                logger.info("成功进入方法");
                Channel channel = future.channel();
                String id = future.channel().id().toString();
                BootNettyClientChannel bootNettyClientChannel = new BootNettyClientChannel();
                bootNettyClientChannel.setChannel(channel);
                bootNettyClientChannel.setCode(parentConfig.getServerId());
//                BootNettyClientChannelCache.remove(parentConfig.getServerId());//清除缓存
                BootNettyClientChannelCache.save(parentConfig.getServerId(), bootNettyClientChannel);
                //to do 发起一次注册请求
                registerToServer(bootNettyClientChannel,parentConfig);
                future.channel().closeFuture().sync();
            }
        } catch (Exception e) {
            logger.error("上级系统{}:{},区域巡视主机无法连接到服务器{}！",ServerIP,Serverport,parentConfig.getParentId());
        } finally {
            /**
             * 退出，释放资源
             */
            group.shutdownGracefully().sync();
        }

    }

    private void registerToServer(BootNettyClientChannel bootNettyClientChannel, ParentConfig parentConfig){
        StringRedisTemplate redisTemplate = SpringContextHolder.getBean(StringRedisTemplate.class);
        //getXml(String SendCode, String ReceiveCode, String Type, String Command, String Code, List< Map > items)
        String xml=MyXmlUtil.getXml(parentConfig.getServerId(),parentConfig.getParentId(), SystemCode.TYPE_SYSTEM_MESSAGE_CODE.getCode(),SystemCode.COMMAND_REGISTER_CODE.getCode(),"",null);
        logger.info("注册xml"+xml);
        MyMessageProtocol messageProtocol = new MyMessageProtocol();
        long requestSessionID = BootSessionCache.getRequestSessionID();
        messageProtocol.setSenderSerialNo(requestSessionID);
        redisTemplate.opsForValue().set(Constant.CLOUD_SEND_CODE + requestSessionID, xml);
        messageProtocol.setReceiverSerialNo(0L);
        messageProtocol.setSessionflag(0);
        messageProtocol.setXmllen(xml.getBytes(CharsetUtil.UTF_8).length);
        messageProtocol.setXmlcontent(xml.getBytes(CharsetUtil.UTF_8));
        if(bootNettyClientChannel != null && bootNettyClientChannel.getChannel().isOpen()){
            logger.info("通道是通的");
            bootNettyClientChannel.getChannel().writeAndFlush(messageProtocol);
        }else{
            logger.info("通道是关的");
        }
    }


}
