package co.dc.aptiv.mina;

import co.dc.commons.utils.DateTimeUtil;
import co.dc.aptiv.AptivApp;
import co.dc.aptiv.ScanFrame;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.serial.SerialAddress;
import org.apache.mina.transport.serial.SerialAddress.DataBits;
import org.apache.mina.transport.serial.SerialAddress.FlowControl;
import org.apache.mina.transport.serial.SerialAddress.Parity;
import org.apache.mina.transport.serial.SerialAddress.StopBits;
import org.apache.mina.transport.serial.SerialConnector;

import java.util.HashMap;
import java.util.Map;

/**
 * com 连接plc <br/>
 * <p>
 * [0xFF,0x00,0x00,0x06,0x01,0x06] 查询激光机状态 ; <br/>
 * [0xFF,0x00,0x00,0x0C,0x06,0x01,0x01,0x00,0x00,0x00,0x00,0x13] 激光机文本参数设置  <br/>
 * [0x36, 0x36, 0x3B, 0x0D, 0x0A] 开警报 66; <br/>
 * 红灯 [0x32, 0x32, 0x3B, 0x0D, 0x0A] 开喷码警报 22; <br/>
 * 黄灯 [0x33, 0x33, 0x3B, 0x0D, 0x0A] 开采集警报 33; <br/>
 * 蓝灯 [0x37, 0x37, 0x3B, 0x0D, 0x0A] 关警报 77; <br/>
 * [0x41, 0x54, 0x3B, 0x0D, 0x0A] A道喷码机触发器 AT; <br/>
 * [0x42, 0x54, 0x3B, 0x0D, 0x0A] B道喷码机触发器 BT; <br/>
 *
 * @author mx
 */
//@Service("comMinaA")
public class ComMinaA extends MinaAbstract {

    private static final Log log = LogFactory.getLog(ComMinaA.class);


    private static boolean status = false;

    public static int flag = 0;
    // 报警状态
    public static Map<String, Boolean> waringStatus = new HashMap<String, Boolean>();
    // 上次握手时间
    private long lastConnectTime = 0;
    // 波特率
    private int bot;
    // COM端口
    private String com;

    private QueryRunner queryRunner;

    private ScanFrame scanFrame;

    @Override
    public void init(boolean init) {
        // 创建串口通信的客户端
        connector = new SerialConnector();

        connector.getFilterChain().addLast("log", new LoggingFilter());

        // 设置连接超时检查时间
        connector.setConnectTimeoutCheckInterval(15);
        // connector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        // 读写都空闲时间:30秒
        connector.getSessionConfig().setIdleTime(IdleStatus.READER_IDLE, 10);

        // 添加处理器
        connector.setHandler(new MinaAbstractHandler(this, queryRunner) {


            // 接收到信息后触发的方法
            @Override
            public void messageReceived(IoSession session, Object message) throws Exception {
                IoBuffer in = (IoBuffer) message;
                byte[] bytes = new byte[in.remaining()];
                in.get(bytes, 0, in.remaining());
                String s = Integer.toHexString(bytes[0]);
                if (s != null) {
                    if ("ok".equals(AptivApp.ccu.HexString2String(bytes))) {
//                        AptivApp.scanStatus = true;
                        log.info(DateTimeUtil.getDateTimeString() + " 激光机已成功接收码" );
                        getScanFrame().changeLight(getScanFrame().label_scan1, true);
                    }
                }
            }

            @Override
            public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
            }

        });

        log.info("com232 mina 服务启动com[" + com + "] bot[" + bot + "]");

        SerialAddress address = new SerialAddress(com, bot, DataBits.DATABITS_8, StopBits.BITS_1, Parity.NONE, FlowControl.NONE);

        connector.setDefaultRemoteAddress(address);

    }

    public ComMinaA(String com, int bot) {
        this.bot = bot;
        this.com = com;
    }

    public boolean isConnectStatus() {
        // 要保证 连接状态和 握手时间都正常的情况 才算正常
        return (super.isConnect() && checkConnectTime());
    }


    public boolean checkConnectTime() {
        return (System.currentTimeMillis() - lastConnectTime) < 1000 * 60;
    }

    public static boolean isStatus() {
        return status;
    }

    public static void setStatus(boolean status) {
        ComMinaA.status = status;
    }

    public static boolean isWaringStatus() {
        boolean status = false;
        if (waringStatus != null && waringStatus.size() > 0) {
            for (boolean b : waringStatus.values()) {
                status |= b;
            }
        }
        return status;
    }

    public ScanFrame getScanFrame() {
        return scanFrame;
    }

    public void setScanFrame(ScanFrame scanFrame) {
        this.scanFrame = scanFrame;
    }


}