package  org.ts.ddcs.datatemplate.szyDataTemplate;

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;



/**
 * 2012 规约报文数据模板
 *
 * @author dylan
 */
public class DataTemplate2012 extends DataTemplate implements DataTemplateInterface {

    /**
     * 报文开头 2012年 68H 开头
     */
    protected byte packetHeader = 0;
    /**
     * 报文长度(int)
     */
    protected int len = 0;
    /**
     * 报文开头 2012年 68H 开头
     */
    protected byte packetHeader2 = 0;
    /**
     * 控制域
     */
    protected byte ca;
    /**
     * 测站编码
     */
    protected byte[] rtuCode;
    /**
     * 命令(HEX_2)
     */
    protected byte[] command;

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

    @Override
    public void stream(DataStreamInterface stream) {
        if (stream.dataSize() == 0) {
            return;
        }
        if (stream.getByte(0) != 0x68) {
            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;
        }
        byte[] bodySize = new byte[1];
        bodySize[0] = stream.getByte(1);
        int len = bodySize[0] < 0 ? bodySize[0] + 256 : bodySize[0];
        len += 3;
        this.length = 2 + len;
        if (stream.dataSize() < this.length) {
            return;
        }
        this.packet = stream.getBytes(this.length);
        int count = 0;
        this.packetHeader = this.packet[count];
        count += 1;
        this.len = BytesUtil.byteToInteger(this.packet[count]);
        count += 1;
        this.packetHeader2 = this.packet[count];
        count += 1;
        this.ca = this.packet[count];
        count += 1;
        this.rtuCode = new byte[5];
        System.arraycopy(this.packet, count, this.rtuCode, 0, 5);
        count += 5;
        this.command = new byte[1];
        this.command[0] = this.packet[count];
        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() {
        this.state = TestState.LOOK;
    }

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

    @Override
    public TestState state() {
        return this.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.command;
    }

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

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

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

    @Override
    public boolean hasNext() {
        return false;
    }

    @Override
    public int packageTotal() {
        return 0;
    }

    @Override
    public int packageIndex() {
        return 0;
    }

    @Override
    public byte[] body() {
        return new byte[0];
    }
}
