package com.cisdi.data.XRFRIGHT;

import com.alibaba.fastjson.JSON;
import com.cisdi.data.XRFRIGHT.impl.XRFRightChannelInitializer;
import com.cisdi.data.XRFRIGHT.impl.XRFRightIoSession;
import com.cisdi.data.XRFRIGHT.impl.XRFRightSessionFactory;
import com.cisdi.data.common.exception.BusinessException;
import com.cisdi.data.sdk.consts.ServiceName;
import com.cisdi.data.sdk.enums.GatewayState;
import com.cisdi.data.sdk.gateway.base.SocketGatewayBase;
import com.cisdi.data.sdk.gateway.netty.IoSession;
import com.cisdi.data.sdk.gateway.netty.SessionFactory;
import com.cisdi.data.sdk.gateway.netty.TcpIoService;
import com.cisdi.data.sdk.gateway.netty.impl.DefaultTcpIoService;
import com.cisdi.data.sdk.param.ListenSocketParam;
import com.cisdi.data.sdk.procotol.message.SocketReturnMessage;
import com.cisdi.data.sdk.service.PlatformService;
import com.cisdi.data.sdk.service.RouteService;
import com.cisdi.data.sdk.vo.DeviceVo;
import com.cisdi.data.sdk.vo.ExeResultVo;
import com.cisdi.data.sdk.vo.SslConfigVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author cuianbing
 * @version 1.0
 * @description: TODO
 * @date 2021/7/7 19:18
 */
@Slf4j
public class XRFRightSocketGateway extends SocketGatewayBase {


    TcpIoService ioService = null;
    SessionFactory sessionFactory = null;

    // 当配置为单个设备模式时，此为该设备id
    String onlyOneDeviceId = null;

    @Override
    public ExeResultVo sendReturnMessage(SocketReturnMessage socketReturnMessage) {
        throw new BusinessException("X射线荧光光谱仪不支持下发服务！");
    }

    @Override
    public void start() {
        if (state == GatewayState.RUNNING) {
            return;
        }
        log.info("网关:{}读取启动配置参数:{},是否支持支持多个设备:{}", instanceVo.getRunId(), instanceVo.getParameter(),
                instanceVo.getSuportMultiDevice());


        // 不支持多个设备，必须强制配置一个设备id
        if (instanceVo.getSuportMultiDevice() != null && instanceVo.getSuportMultiDevice() == false) {
            RouteService routeService = (RouteService) serviceProvider.getByName(ServiceName.Route);
            List<DeviceVo> deviceVos = routeService.findByRunId(instanceVo.getRunId());

            if (deviceVos.size() > 1) {
                throw new BusinessException("网关Id:" + instanceVo.getRunId() + "为X射线荧光光谱仪网关，当前配置为只支持单个设备，但配置了多个设备。");
            }

            onlyOneDeviceId = deviceVos.size() > 0 ? deviceVos.get(0).getDeviceId() : null;

            if (StringUtils.isEmpty(onlyOneDeviceId)) {
                throw new BusinessException("runId=" + getInstanceVo().getRunId() + "未正确配置网关和设备关联");
            }
        }


        DefaultTcpIoService defaultIoService = new DefaultTcpIoService();
        SessionFactory factory = new XRFRightSessionFactory(onlyOneDeviceId);
        factory.init(serviceProvider, this);

        SslConfigVo sslConfigVo = null;

        ListenSocketParam socketParam = JSON.parseObject(getInstanceVo().getParameter(), ListenSocketParam.class);

        if (socketParam != null && Boolean.TRUE.equals(socketParam.getEnableSsl())) {

            PlatformService platformService = (PlatformService) serviceProvider.getByName(ServiceName.Platform);

            sslConfigVo = platformService.getSslConfig();
        }


        XRFRightChannelInitializer channelInitializer =
                new XRFRightChannelInitializer(factory, getInstanceVo().getByteOrder(), sslConfigVo);

        defaultIoService.init(instanceVo, factory, channelInitializer);

        ioService = defaultIoService;
        sessionFactory = factory;

        boolean open = ioService.open();

        if (open == true) {
            state = GatewayState.RUNNING;
            log.info("X射线荧光光谱仪网关:{}启动成功 参数:{}", instanceVo.getRunId(), getInstanceVo().getParameter());

        } else {
            log.info("X射线荧光光谱仪网关:{}启动失败 参数:{}", instanceVo.getRunId(), getInstanceVo().getParameter());
        }

    }

    @Override
    public void shutdown() {
        if (state == GatewayState.CLOSED) {
            return;
        }

        if (sessionFactory != null) {
            for (IoSession ioSession : sessionFactory.getSessions()) {
                XRFRightIoSession xrfRightIoSession = (XRFRightIoSession) ioSession;
                xrfRightIoSession.close();
            }
        }

        boolean close = ioService.close();
        if (close == true) {
            sessionFactory = null;
            state = GatewayState.CLOSED;
            log.info("X射线荧光光谱仪网关:{}关闭成功", instanceVo.getRunId());
        } else {
            log.info("X射线荧光光谱仪网关:{}关闭失败", instanceVo.getRunId());
        }
    }

    @Override
    public Set<String> getActiveDeviceIds() {
        if (onlyOneDeviceId != null) {
            Set<String> set = new HashSet<String>();
            set.add(onlyOneDeviceId);
            return set;
        } else {
            return sessionFactory.getActiveDeviceIds();
        }
    }
}
