package com.imdroid.sideslope.executor;

import com.imdroid.secapi.dto.GnssDevice;
import com.imdroid.sideslope.message.D331RtcmMessage;
import com.imdroid.sideslope.sal.Device;
import com.imdroid.sideslope.sal.DeviceService;
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.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;

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

        String id = message.getId();
        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);
            });
        }
        return null;
    }

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