/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称: 大恒泰山系统
 * 创建日期:2021/12/16
 */
package org.ts.ddcs.dataStream.processor.sw;


import lombok.extern.slf4j.Slf4j;
import org.ts.ddcs.common.constant.SwDatagramConstant;
import org.ts.ddcs.common.util.BytesHelp;
import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
import org.ts.ddcs.dataStream.DataStreamAdapter;
import org.ts.ddcs.dataStream.DataStreamCache;
import org.ts.ddcs.dataStream.DataStreamLineManager;
import org.ts.ddcs.dataStream.DataStreamProcessor;
import org.ts.ddcs.datatemplate.TestState;
import org.ts.ddcs.metadata.DataStreamCacheMetadata;

import java.util.List;
import java.util.Map;

;

/***
 * Date:2021/12/16
 * Title:数据处理器模块
 * Description： 报文检测处理器，主要负责检测出一个完整正确的报文
 * @author dylan
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@Slf4j
public class DataStreamSwExtMatchProcessor extends DataStreamProcessor {

    private DataStreamCache dataStreamCache;

    @Override
    public void init(DataStreamLineManager context) {
        this.context = context;
        this.dataStreamCache = context.getCache();
    }

    @Override
    public void process(DataStreamAdapter dataStreamAdapter) {
        this.dataStreamCache.setState(TestState.LOOK);
        this.dataStreamCache.setMatchProcessor(this);
        byte[] block = dataStreamAdapter.getBlock();
        if (block.length == 0) {
            this.next(false);
        }
        this.dataStreamCache.setDataBuff(block);
        if (dataStreamCache.dataSize() < 2) {
            this.next(false);
        }
        if (dataStreamCache.getByte(0) != 0x7E || dataStreamCache.getByte(1) != 0x7E) {
            dataStreamCache.setState(TestState.ERROR);
            this.next(false);
        }
        if (dataStreamCache.dataSize() < SwDatagramConstant.FEATURE_WEIGHT) {
            this.next(false);
        }
        // 报文正文长度
        byte[] dataAreaLen = new byte[2];
        dataAreaLen[0] = dataStreamCache.getByte(11);
        dataAreaLen[1] = dataStreamCache.getByte(12);
        int contentLen = Sw2014DatagramTemplateHelp.getContentLen(dataAreaLen);
        int datagramSize = 11 + contentLen + 6;
        if (dataStreamCache.dataSize() < datagramSize) {
            this.next(false);
        }
        dataStreamCache.setDatagramSize(datagramSize);
        byte[] datagramBuff = dataStreamCache.getBytes(datagramSize);
        dataStreamCache.setDatagramBuff(datagramBuff);
        int count = 0;
        byte[] packetHeader = BytesHelp.subBytes(datagramBuff, count, 2);
        count += 2;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_PACKET_HEADER.getName(), packetHeader);
        //中心站地址
        byte[] centerStation = BytesHelp.subBytes(datagramBuff, count, 1);
        count += 1;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName(), centerStation);
        //RTU地址
        byte[] rtuCodeByte = BytesHelp.subBytes(datagramBuff, count, 8);
        count += 8;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName(), rtuCodeByte);
        //RTU密码
        byte[] rtuPw = BytesHelp.subBytes(datagramBuff, count, 2);
        count += 2;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SW_PW.getName(), rtuPw);
        //功能码
        byte[] funcCode = BytesHelp.subBytes(datagramBuff, count, 1);
        count += 1;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName(), funcCode);
        //byte[] datagramCode = dataStreamCache.getBytes(DatagramConstant.featureWeight - 1, 1);
        // dataStreamCache.setDatagramCode(BytesHelp.byte2HexStr(funcCode));

        //byte command = funcCode[0];
        //dataStreamCache.putValue("command", (int) command);
        //报文上下行标识及长度  高四位用作上下行标识（0000 表示上行，1000，表示下行）；
        //其余12位表示报文正文长度，表示报文起始符之后，报文结束符之前的报文字节数，允许长度为0001-4095
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_LEN.getName(), dataAreaLen);
        count += 2;
        //报文起始符
        byte[] dataAreaStartFlag = BytesHelp.subBytes(datagramBuff, count, 1);
        count += 1;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName(), dataAreaStartFlag);
        //报文正文
        byte[] dataArea = BytesHelp.subBytes(datagramBuff, count, contentLen);
        count += contentLen;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName(), dataArea);
        //报文结束符
        byte[] dataAreaEndFlag = BytesHelp.subBytes(datagramBuff, count, 1);
        count += 1;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_END_FLAG.getName(), dataAreaEndFlag);
        //校验码
        byte[] packetCrc16 = BytesHelp.subBytes(datagramBuff, count, 2);
        count += 2;
        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_CRC.getName(), packetCrc16);
        dataStreamCache.setReadSize(dataStreamCache.getDatagramSize());
        dataStreamCache.setState(TestState.MATHCE);
        this.next(true);
    }

    @Override
    public void close(DataStreamAdapter dataStreamAdapter) {
//        if (this.dataStreamCache.getState() == TestState.ERROR) {
//            this.dataStreamCache.setMatchProcessor(this);
//        }
    }

    @Override
    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
        if (dataStreamCache.getState() == TestState.ERROR) {
            int size = this.dataStreamCache.dataSize();
            int count = 0;
            for (int i = 1; i < size; i++) {
                byte v = dataStreamCache.getByte(i);
                if (v == 0x7E) {
                    count = i;
                    break;
                }
            }
            if (count > 0) {
                dataStreamCache.setReadSize(count);
            } else {
                dataStreamCache.setReadSize(size);
            }
        }
//        else if (dataStreamCache.getState() == TestState.MATHCE) {
//            dataStreamCache.setReadSize(dataStreamCache.getDatagramSize());
//        }
    }

    @Override
    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
        return null;
    }


}
