package com.mortals.xhx.daemon.netty.server.controlserver.handler;

import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.ServerInfo;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.utils.EncryptUtil;
import com.mortals.xhx.module.device.service.DeviceService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.net.*;
import java.util.Enumeration;

import static com.mortals.xhx.common.key.Constant.*;


/**
 * 业务处理
 *
 * @author: zxfei
 * @date: 2022/4/8 10:20
 */
@Slf4j
public class NettyUDPServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {


    //@Value("${application.registerApiPath:/api/register}")
    private String registerApiPath = "/api/register";
    //@Value("${application.deviceInitApiPath:/api/deviceInit}")
    private String deviceInitApiPath = "/api/deviceInit";
    //@Value("${application.deviceUpdateApiPath:/api/deviceUpdate}")
    private String deviceUpdateApiPath = "/api/deviceUpdate";
    //@Value("${server.servlet.context-path:/m}")
    private String servletPath = "/m";


    private DeviceService deviceService;

    public NettyUDPServerHandler(DeviceService deviceService) {
        this.deviceService = deviceService;


    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {

       // String serverPort = SpringUtil.getProperty("server.port");
        String serverPort = "11091";

        ByteBuf byteBuf = packet.copy().content();
        byte[] bytes = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(bytes);
        String content = new String(bytes);
        ApiResp<ServerInfo> resp = new ApiResp<>();
        resp.setCode(YesNoEnum.YES.getValue());
        log.info("receive->UDP entbefore:{}", packet.sender().toString() + "," + content);
        try {
            content = EncryptUtil.myReEnscrt(content, 9, DES_STR, ENCRYPT_STR);
            //EncryptUtil.decrypt(content, ENCRYPT_STR);
            log.info("receive->UDPafter:{}", packet.sender().toString() + "," + content);
            JSONObject jsonObject = JSON.parseObject(content);
            String action = jsonObject.getString("action");
            resp.setMsg("获取服务端地址成功！");
            if (!ObjectUtils.isEmpty(action) && "findserver".equals(action)) {
                String domain = GlobalSysInfo.getParamValue(PARAM_SERVER_HTTP_URL, "http://192.168.0.98:11091");
/*                String currentIp = getInet4Address();
                if (currentIp != null) {
                    domain = "http://" + currentIp + ":" + serverPort;
                } else {
                    domain = GlobalSysInfo.getParamValue(PARAM_SERVER_HTTP_URL, "http://192.168.0.98:11091");
                }*/
                URL url = URLUtil.url(domain);
                log.info("getServerUrl:" + domain);
                String deviceRegisterApi = servletPath + registerApiPath;
                String deviceInitApi = servletPath + deviceInitApiPath;
                String deviceUpdateApi = servletPath + deviceUpdateApiPath;

                ServerInfo serverInfo = new ServerInfo();
                serverInfo.setIp(url.getHost());
                serverInfo.setPort(url.getPort());
                serverInfo.setDeviceRegisterApi(deviceRegisterApi);
                serverInfo.setDeviceInitApi(deviceInitApi);
                serverInfo.setDeviceUpdateApi(deviceUpdateApi);
                resp.setData(serverInfo);
            } else {
                resp.setCode(YesNoEnum.NO.getValue());
                resp.setMsg("请求参数异常！");
            }

            InetSocketAddress remoteAddress = new InetSocketAddress(packet.sender().getHostName(), CLIENT_PORT);
            String sa = EncryptUtil.myEnscrt(JSON.toJSONString(resp), 9, DES_STR, ENCRYPT_STR);
//            log.info("enStr:{}",sa);
//            log.info("deEncrypt:{}", EncryptUtil.myReEnscrt(sa, 9, DES_STR, ENCRYPT_STR));
            DatagramPacket sendpacket = new DatagramPacket(Unpooled.copiedBuffer(sa, CharsetUtil.UTF_8), remoteAddress);
            //ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(JSON.toJSONString(resp), CharsetUtil.UTF_8), packet.sender()));
            ctx.writeAndFlush(sendpacket);
        } catch (Exception e) {
            log.error("异常", e);
            resp.setCode(YesNoEnum.NO.getValue());
            resp.setMsg("加密解密异常！");
        }
    }

    public static InetAddress getCurrentIp() {
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) networkInterfaces.nextElement();
                Enumeration<InetAddress> nias = ni.getInetAddresses();
                while (nias.hasMoreElements()) {
                    InetAddress ia = (InetAddress) nias.nextElement();
                    if (!ia.isLinkLocalAddress() && !ia.isLoopbackAddress() && ia instanceof Inet4Address) {
                        return ia;
                    }
                }
            }
        } catch (SocketException e) {
            log.error("获取ip异常", e);
        }
        return null;
    }

    public static String getInet4Address() {
        Enumeration<NetworkInterface> nis;
        String ip = null;
        try {
            nis = NetworkInterface.getNetworkInterfaces();
            for (; nis.hasMoreElements(); ) {
                NetworkInterface ni = nis.nextElement();
                Enumeration<InetAddress> ias = ni.getInetAddresses();
                for (; ias.hasMoreElements(); ) {
                    InetAddress ia = ias.nextElement();
                    //ia instanceof Inet6Address && !ia.equals("")
                    if (ia instanceof Inet4Address && !ia.getHostAddress().equals("127.0.0.1")) {
                        ip = ia.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ip;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // TODO Auto-generated method stub
        ctx.close();
        cause.printStackTrace();
    }


    public static void main(String[] args) {
        String domain="http://192.168.0.98:11801";
        URL url = URLUtil.url(domain);

        System.out.println(url.getHost());
        System.out.println(url.getPort());

/*        InetAddress currentIp = NettyUDPServerHandler.getCurrentIp();
        System.out.println(currentIp.getHostName());
        System.out.println(getInet4Address());*/

    }
}
