package com.cisdi.data.OBLF.impl;

import com.alibaba.fastjson.JSON;
import com.cisdi.data.common.exception.BusinessException;
import com.cisdi.data.sdk.consts.ServiceName;
import com.cisdi.data.sdk.gateway.message.SocketMessage;
import com.cisdi.data.sdk.gateway.netty.IoSession;
import com.cisdi.data.sdk.gateway.netty.impl.AbstractIoSession;
import com.cisdi.data.sdk.service.PassthroughService;
import com.cisdi.data.sdk.service.SendService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author cuianbing
 * @version 1.0
 * @description: TODO
 * @date 2021/7/20 21:28
 */
@Slf4j
public class OBLFIoSession extends AbstractIoSession implements IoSession {

    private OBLFSessionFactory factory = null;

    private String deviceId = null;
    /**
     * 如果有值，代表所有会话都使用这一个设备id，且允许多会话共享此一个设备id，不除旧会话
     */
    private final String onlyOneDeviceId;

    private String gwPrefixCache = null;

    private ByteBuf allBuf = ByteBufAllocator.DEFAULT.buffer();


    public OBLFIoSession(OBLFSessionFactory factory, String onlyOneDeviceId) {
        super();
        this.factory = factory;
        this.onlyOneDeviceId = onlyOneDeviceId;
    }

    @Override
    public String[] getDeviceIds() {
        String cpDeviceId = deviceId;
        String[] result = new String[cpDeviceId == null ? 0 : 1];
        if (cpDeviceId != null) {
            result[0] = cpDeviceId;
        }
        return result;
    }

    @Override
    public void onRead(Object message) {
        try {

            ByteBuf inBuf = (ByteBuf) message;
            if (inBuf != null) {
                allBuf.writeBytes(inBuf);
            } else {
                log.info("电文格式为空");
            }
        } catch (Exception e) {
            log.error("电文格式错误！");
            throw new BusinessException("电文格式错误！");
        }

    }

    @Override
    public void onOpen() {
        super.onOpen();
        log.info("建立连接，channel:{}", getChannel());
    }

    @Override
    public void onClose() {
        log.info("onClose");
        Map<String, String> message = decode(allBuf);

        if (serviceProvider != null && socketGateway != null) {
            SendService service = (SendService) serviceProvider.getByName(ServiceName.Send);
            SocketMessage socketMessage = socketGateway.buildSocketMessage();
            socketMessage.setDeviceId(onlyOneDeviceId);
            socketMessage.setData(JSON.toJSONString(message).getBytes(StandardCharsets.UTF_8));

            String analysisProgram = message.get("AnalysisProgram_");

            if ("FE 4".equals(analysisProgram)) {
                socketMessage.setMsgKey("iron");
            } else {
                socketMessage.setMsgKey("steel");
            }

            service.sendMessage(socketMessage);
            if (socketGateway.getInstanceVo().getLogOpen()) {
                log.info("类似为:{}:发送消息内容{}", message, message.toString());
            }

        }
        super.onClose();
        factory = null;
    }


    public void close() {
        if (getChannel() != null) {
            try {
                getChannel().close().sync();
            } catch (InterruptedException e) {
                log.warn(e.getLocalizedMessage(), e);
            }
        }
    }

    @Override
    public void onError(Throwable t) {
        // 这里会出现 java.io.IOException: 远程主机强迫关闭了一个现有的连接。
        log.info("远程主机强迫关闭了一个现有的连接。");
//        log.error("session exception:{}", t);
    }


    public Map<String, String> decode(ByteBuf byteBuf) {

        List<Map<String, String>> dataList = new ArrayList<>();
        AtomicInteger dataFlag = new AtomicInteger();

        String msg = byteBuf.toString(StandardCharsets.UTF_8);
        Map<String, String> data = JSON.parseObject(msg, Map.class);
        log.debug("收到数据{}", data);
        return data;
    }


    private void passThrough(ByteBuf passthroughBuf) {
        try {
            if (serviceProvider != null && socketGateway != null) {
                PassthroughService service = (PassthroughService) serviceProvider.getByName(ServiceName.Passthrough);
                service.transfer(passthroughBuf, socketGateway.getInstanceVo().getPassthroughAddress());
            }
        } catch (Exception e) {
            log.error("协议透传失败：" + e.getLocalizedMessage(), e);
        }
    }

    public String gwPrefix() {
        if (gwPrefixCache != null) {
            return gwPrefixCache;
        }

        gwPrefixCache = "";
        if (socketGateway != null && socketGateway.getInstanceVo() != null) {
            gwPrefixCache = "网关Id:" + socketGateway.getInstanceVo().getRunId() + "连接:" + getChannel() + " ";
        } else {
            gwPrefixCache = "连接:" + getChannel() + " ";
        }

        return gwPrefixCache;
    }


}
