package com.imdroid.sideslope.executor;

import com.imdroid.secapi.client.BeidouClient;
import com.imdroid.sideslope.bd.Gga;
import com.imdroid.sideslope.calc.GNSSDataCalcService;
import com.imdroid.sideslope.message.D341LocationMessage;
import com.imdroid.sideslope.sal.Device;
import com.imdroid.sideslope.sal.DeviceService;
import com.imdroid.common.util.ThreadManager;
import com.imdroid.sideslope.server.DeviceChannel;
import com.imdroid.sideslope.server.OnlineChannels;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author Layton
 * @date 2023/2/2 20:50
 */
@Component
public class D341LocationMessageExecutor implements Executor<D341LocationMessage, Void> {

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

    @Autowired
    private GNSSDataCalcService gnssCalcService;
    @Resource(name = "local")
    private DeviceService deviceService;
    @Autowired
    private BeidouClient beidouClient;
    @Override
    public Void execute(D341LocationMessage message) {
        if (logger.isDebugEnabled()) {
            logger.debug("receive d341 message of device: "+message.getId()+", seq:"+message.getSeq()+", len:"+message.getLen());
        }
        // 补齐tenantId，要求快速处理，因此用缓存，不要每次都查数据库
        Device device = deviceService.findByDeviceId(message.getId());
        if(device == null) return null;
        message.setTenantId(device.getTenantId());
        device.updateRx(message.getHeader(), message.getLen(), 1);
        Gga gga = message.getGga();
        if(gga != null) {
            device.updateSatelitesNum(gga.getSatellitesInUsed());
            if(gga.getQuality()>0 && gga.getQuality()<6) {
                device.setLatitude(gga.getLatitude());
                device.setLongitude(gga.getLongitude());
                device.setAltitude(gga.getAltitude());
            }
        }

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

                }
            }
        }

        ThreadManager.getFixedThreadPool().submit(() -> {
            gnssCalcService.calcSingle(message,true);
        });

        return null;
    }

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