package com.imdroid.sideslope.executor;

import com.imdroid.secapi.client.BeidouClient;
import com.imdroid.secapi.dto.GnssDevice;
import com.imdroid.sideslope.bd.Gga;
import com.imdroid.sideslope.message.D331RtcmMessage;
import com.imdroid.sideslope.sal.Device;
import com.imdroid.sideslope.sal.DeviceService;
import com.imdroid.sideslope.server.DeviceChannel;
import com.imdroid.sideslope.server.OnlineChannels;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author Layton
 * @date 2023/2/2 20:49
 */
@Component
public class D331RtcmMessageExecutor implements Executor<D331RtcmMessage, Void> {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource(name = "local")
    private DeviceService deviceService;
    @Autowired
    private BeidouClient beidouClient;

    @Override
    public Void execute(D331RtcmMessage message) {
        String id = message.getId();
        // 补齐tenantId
        Device device1 = deviceService.findByDeviceId(id);
        if(device1 == null || device1.getOpMode() == GnssDevice.OP_MODE_UNUSE) return null;
        if (logger.isDebugEnabled()) {
            logger.debug("receive d331 rtcm message of device: "+message.getId()+", seq:"+message.getSeq()+", len:"+message.getLen());
        }

        if(device1.getOpMode() == GnssDevice.OP_MODE_USE) {
            byte[] forwardBytes = message.getSrcData();
            // 要求快速转发，因此用缓存，不要每次都查数据库
            List<Device> deviceList = deviceService.findByParentId(id);
            for (Device device : deviceList) {
                if (device.getOpMode() != GnssDevice.OP_MODE_USE) continue;
                String deviceId = device.getDeviceId();
                OnlineChannels.INSTANCE.get(deviceId).ifPresent(deviceChannel -> {
                    if (logger.isDebugEnabled()) {
                        logger.debug("forward d331 rtcm message to device {}", deviceId);
                    }
                    ByteBuf buf = Unpooled.buffer();
                    buf.writeBytes(forwardBytes);
                    deviceChannel.writeAndFlush(buf);
                });
            }
        }

        message.setTenantId(device1.getTenantId());
        device1.updateRx(message.getHeader(),message.getLen(),message.getPacketNum());
        Gga gga = message.getGga();
        if(gga != null) {
            device1.updateSatelitesNum(gga.getSatellitesInUsed());
            if(gga.getQuality()>0 && gga.getQuality()<6) {
                device1.setLatitude(gga.getLatitude());
                device1.setLongitude(gga.getLongitude());
                device1.setAltitude(gga.getAltitude());
            }
            /*logger.info(message.getId()+
                    " lat: "+gga.getLatitude()+
                    " lon:"+gga.getLongitude()+
                    " alt: "+gga.getAltitude()+
                    " sat: "+gga.getSatellitesInUsed()+
                    " quality: "+gga.getQuality());*/
        }

        // 收到第一个数据包，如果控制通道没连接，也通知上线
        if(device1.getD3xxCount() == 1){
            DeviceChannel channel = OnlineChannels.INSTANCE.getConfigChannel(device1.getDeviceId());
            if(channel == null || !channel.isOnline()){
                // 通知上线
                try{
                    beidouClient.onDeviceActive(device1.getDeviceId(), device1.getTenantId());
                }
                catch (Exception e){

                }
            }
        }

        return null;
    }

    @Override
    public Class<?> getMessageType() {
        return D331RtcmMessage.class;
    }
}
