package com.imdroid.sideslope.ntrip;

import com.imdroid.common.util.ByteUtil;
import com.imdroid.common.util.ThreadManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.List;

/**
 * 本地udp发送差分数据到ntrip-forward-server项目
 */
@Service
public class UdpNtripServer {
    private final Logger logger = LoggerFactory.getLogger(UdpNtripServer.class);
    @Value("${ntrip_server.port:9903}")
    private Integer port;
    private DatagramSocket socket;
    private DatagramPacket outPacket;

    /**
     * 向某挂载点提供差分信息
     * @param mount 挂载点名称
     * @param hexRtcm 差分信息16进制字符串
     */
    public void send(String mount, String hexRtcm){
        ThreadManager.getSingleThreadPool(UdpNtripServer.class.getName()).execute(()->{
            try{
                //随机端口
                if(socket == null) socket = new DatagramSocket();
                if(outPacket == null) outPacket = new DatagramPacket(new byte[0],0, InetAddress.getByName("localhost"),port);
                outPacket.setData(encode(ByteUtil.addBytes(mount.getBytes(), ByteUtil.hexStringTobyte(hexRtcm))));
                socket.send(outPacket);
            }catch (Exception e){
                socket = null;
                outPacket = null;
                e.printStackTrace();
            }
        });
    }

    /**
     * 向某挂载点提供差分信息
     * @param mount 挂载点名称
     * @param hexRtcm 差分信息16进制字符串
     */
    public void send(String mount, List<String> hexRtcm){
        logger.debug(mount + ":" + hexRtcm.size());
        for (String s : hexRtcm) {
            send(mount,s);
        }
    }

    //加入校验位，用于校验数据是否完整
    private byte[] encode(byte[] bytes) {
        byte[] bytes1 = new byte[bytes.length + 1];
        //校验位
        byte b = bytes[0];
        bytes1[0] = bytes[0];
        for (int i = 1; i < bytes.length; i++) {
            b ^= bytes[i];
            bytes1[i] = bytes[i];
        }
        bytes1[bytes1.length - 1] = b;
        return bytes1;
    }
}
