/**
 * 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.enums.SwDatagramTypeCodeEnum;
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.itemdatatemplate.DataItemTemplate;
import org.ts.ddcs.metadata.DataStreamCacheMetadata;


import java.io.UnsupportedEncodingException;

import java.util.*;

/***
 * Date:2021/12/16
 * Title:数据处理器模块
 * Description：图片报 0x36
 * @author dylan
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@Slf4j
public class DataStreamSwImageDatagramProcessor extends DataStreamProcessor {

    private DataStreamCache dataStreamCache;
    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
    private int packpagSize;
    private int packpageCount;

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

    @Override
    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
        this.dataStreamCache.setState(TestState.MATHCE);
        this.dataStreamCache.setMatchProcessor(this);
        String datagramCode = this.dataStreamCache.getDatagramCode();
        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_36.getName().equals(datagramCode)) {
            String agreement = dataStreamAdapter.getAgreement();
            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
            int count = 0;
            byte[] packIndex = BytesHelp.subBytes(dataArea, count, 3);
            int indexValue = BytesHelp.bytes2Int(packIndex, 0, 3);
            this.packpagSize = (indexValue >> 12) & 0x0FFF;
            this.packpageCount = indexValue & 0x0FFF;
            count += 3;
            if (packpageCount == 1) {
                //流水号
                byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
                count += 2;
                //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
                // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
                // 发报时间
                byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
                count += 6;
                //遥测站地址
                DataItemTemplate itemTemplateSt = itemTemplateMap.get("F1");
                // itemTemplateSt.clear();
                int readSize = itemTemplateSt.stream(dataArea, count);
                if (itemTemplateSt.isMacth()) {
                    itemTemplateSt.saveValue(this.keyStore);
                }
                count += readSize;
                //遥测站分类码
                byte[] siteKind = BytesHelp.subBytes(dataArea, count, 1);
                count += 1;
                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName(), BytesHelp.byte2HexStr(siteKind));
                //采集时间
                DataItemTemplate itemTemplateTt = itemTemplateMap.get("F0");
                // itemTemplateSt.clear();
                readSize = itemTemplateTt.stream(dataArea, count);
                if (itemTemplateSt.isMacth()) {
                    itemTemplateSt.saveValue(this.keyStore);
                }
                count += readSize;
                dataStreamAdapter.putValue("packpagSize", packpagSize);
                if (dataArea.length - count > 0) {
                    count += 2;
                    if (dataArea.length - count > 0) {
                        byte[] imageData = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
                        if (null != imageData && imageData.length > 0) {
                            dataStreamAdapter.putValue(String.format("imageData%d", packpageCount), imageData);
                        }
                    }
                }
            } else if (packpagSize == packpageCount) {
                if (dataArea.length - count > 0) {
                    byte[] imageData = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
                    if (null != imageData && imageData.length > 0) {
                        dataStreamAdapter.putValue(String.format("imageData%d", packpageCount), imageData);
                    }
                }
            } else {
                if (dataArea.length - count > 0) {
                    byte[] imageData = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
                    if (null != imageData && imageData.length > 0) {
                        dataStreamAdapter.putValue(String.format("imageData%d", packpageCount), imageData);
                    }
                }
            }
            this.next(false);
        } else {
            this.next(true);
        }
    }

    @Override
    public void close(DataStreamAdapter dataStreamAdapter) {

    }

    @Override
    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
        log.info("接收到36图片报,回复报文");
        byte[] respPacket = new byte[2];
        //帧起始符
        respPacket[0] = 0x7e;
        respPacket[1] = 0x7e;
        //遥测站地址
        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
        //中心站地址
        byte[] centerStationByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
        //密码
        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
        //功能码
        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
        //报文下行标识及长度
        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
        //报文起始符
        byte[] ps = new byte[1];
        ps[0] = 0x02;
        respPacket = BytesHelp.arrayApend(respPacket, ps);

        // byte[] packIndex = BytesHelp.subBytes(packetContext, 14, 3);
        //int indexValue = BytesHelp.bytes2Int(packIndex, 0, 3);
        // int total = (indexValue >> 12) & 0x0FFF;
        //  int count = indexValue & 0x0FFF;
        //流水号
        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
        //发报时间
        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
        //RTU2014年报文正文结束符
        if (this.packpageCount == 1) {
            ps[0] = 0x05;
            respPacket = BytesHelp.arrayApend(respPacket, ps);
        } else if (this.packpagSize == this.packpageCount) {
            ps[0] = 0x05;
            respPacket = BytesHelp.arrayApend(respPacket, ps);
        } else {
            ps[0] = 0x05;
            respPacket = BytesHelp.arrayApend(respPacket, ps);
        }
        //CRC16
        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
        respPacket = BytesHelp.arrayApend(respPacket, crc16);
        dataStreamAdapter.output(respPacket);

    }

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


}
