package  org.ts.ddcs.datatemplate.jt_808_2019_template;


import org.ts.ddcs.common.constant.GBConstants;
import org.ts.ddcs.dataStream.DataStreamAdapter;
import org.ts.ddcs.dataStream.DataStreamInterface;
import org.ts.ddcs.dataprocesser.DataProcesserInterface;
import org.ts.ddcs.datatemplate.DataTemplate;
import org.ts.ddcs.datatemplate.DataTemplateInterface;
import org.ts.ddcs.datatemplate.TestState;
import org.ts.ddcs.filter.DataFilter;
import org.ts.ddcs.util.BytesUtil;


/**
 * 交通808-2019规约数据模板
 * created by swp on 2017/8/23
 *
 * @author dylan
 */
public class JtDataTemplate extends DataTemplate implements DataTemplateInterface {

    /**
     * 数据包
     */
    protected byte[] packet;

    /**
     * 功能码
     */
    protected byte[] funcCode;

    /**
     * 正文长度
     */
    protected int bodyLen = 0;

    /**
     * 报文正文
     */
    protected byte[] dataArea;

    /**
     * 版本号
     */
    protected byte[] ver;

    /**
     * 设备号
     */
    protected byte[] deviceId;

    /**
     * 流水号
     */
    protected byte[] datagramIndex;

    /**
     * 分包
     */
    protected boolean hasNext;

    /**
     * 包总数
     */
    protected int packageTotal = 1;

    /**
     * 包序号
     */
    protected int packageIndex;

    /**
     * 加密 1
     */
    protected String rsa;

    /**
     * 检验码
     */
    protected byte[] crc;

    @Override
    public void stream(DataStreamInterface stream) {
        if (stream.dataSize() == 0) {
            return;
        }
        if (stream.getByte(0) != 0x7E) {
            this.state = TestState.UNKNOWN;
            return;
        }
        if (stream.dataSize() < this.featureWeight) {
            return;
        }
        byte[] feature = stream.getBytes(this.featureWeight);
        if (!this.checkFeature(feature, 0, feature.length)) {
            // this.state = TestState.UNKNOWN;
            return;
        }
        int count = 0;
        for (int i = 1; i < stream.dataSize(); i++) {
            if (stream.getByte(i) == 0x7E) {
                count = i;
            }
        }
        if (count == 0) {
            return;
        }

        byte[] tmpBuf = stream.getBytes(0, count + 1);
        String tmpHex = BytesUtil.byte2HexStr(tmpBuf);
        tmpHex = tmpHex.replace("7D01", "7D");
        tmpHex = tmpHex.replace("7D02", "7E");
        tmpBuf = BytesUtil.hexStr2Bytes(tmpHex);

//        int crc = tmpBuf[1];
//        for (int i = 2; i < tmpBuf.length - 2; i++) {
//            crc = crc ^ tmpBuf[i];
//        }
//        int packageCrc = tmpBuf[tmpBuf.length - 2];
//        if (crc != packageCrc) {
//            this.state = TestState.UNKNOWN;
//            return;
//        }

        this.length = count + 1;
        this.packet = tmpBuf;

        this.state = TestState.MATHCE;
    }

    @Override
    public boolean checkFeature(byte[] check, int pos, int length) {
        boolean match = true;
        if (null == this.featureIndex || null == this.featureKey) {
            return match;
        }
        if (length < this.featureKey.length) {
            return false;
        }
        for (int i = 0; i < this.featureIndex.length; i++) {
            if (this.featureKey[this.featureIndex[i]] != check[this.featureIndex[i]]) {
                match = false;
                break;
            }
        }
        return match;
    }

    @Override
    public void ready() {
        state = TestState.LOOK;
    }

    @Override
    public int length() {
        return this.length;
    }

    @Override
    public TestState state() {
        return state;
    }

    @Override
    public int featureWeight() {
        return this.featureWeight;
    }

    @Override
    public void setFeatureWeight(int weight) {
        this.featureWeight = weight;
    }

    @Override
    public String getName() {
        return this.templateName;
    }

    @Override
    public void setName(String name) {
        this.templateName = name;
    }

    @Override
    public void bridgeDataProcessor(DataProcesserInterface processer, DataStreamAdapter dataStreamAdapter) {
        processer.packetReadly(this.packet, 0, this.packet.length, dataStreamAdapter, this);
    }

    @Override
    public boolean bridgeDataFilter(DataFilter filter, DataStreamAdapter dataStreamAdapter) {
        return filter.filter(this.packet, 0, this.packet.length, dataStreamAdapter, this);
    }

    @Override
    public byte[] funcCode() {
        return this.funcCode;
    }

    @Override
    public byte[] rtuCode() {
        return this.deviceId;
    }

    @Override
    public byte[] datagramContext() {
        return this.packet;
    }

    @Override
    public String agreement() {
        return "";
    }

    @Override
    public boolean hasNext() {
        return this.hasNext;
    }

    @Override
    public int packageTotal() {
        return this.packageTotal;
    }

    @Override
    public int packageIndex() {
        return this.packageIndex;
    }

    @Override
    public byte[] body() {
        return this.dataArea;
    }
}
