/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称: 大恒泰山系统
 * 创建日期:2022/3/25
 */
package org.ts.ddcs.dataStream;

import lombok.Data;

import org.ts.ddcs.datatemplate.DataTemplate;
import org.ts.ddcs.datatemplate.TestState;
import org.ts.ddcs.log.LogHelper;
import org.ts.ddcs.util.BytesUtil;

import java.util.LinkedList;
import java.util.List;


/***
 * Date:2022/3/25
 * Title:数据流处理链
 * Description：数据链处理管理器
 * @author dylan
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@Data
public class DataStreamLineManager {
    /**
     * 线程工厂
     */
    //  private static ThreadFactory streamLineThreadFactory = new ThreadFactoryBuilder().setNameFormat("stream-process-pool-%d").build();
    /**
     * 数据流线程池
     */
    //  private ExecutorService dataStreamThreadPool = new ThreadPoolExecutor(1, 1,
    //         0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), streamLineThreadFactory, new ThreadPoolExecutor.AbortPolicy());


    private int bindAgreeementCode;

    public DataStreamLineManager(int agreementCode) {
        this.bindAgreeementCode = agreementCode;
//        if (this.bindAgreeementCode == AgreementEnum.getCode(GBConstants.AGREEMENT_KIND_SW)) {
//            dataStreamCache = new SwDataStreamCache();
//        } else if (this.bindAgreeementCode == AgreementEnum.getCode(GBConstants.AGREEMENT_KIND_SZY)) {
//            dataStreamCache = new SzyDataStreamCache();
//        }

    }

    private List<DataStreamProcessor> processors = new LinkedList<>();

    //   private DataSteam dataSteam = new DataSteam();

    // public DataSteam dataSteam() {
    //  return this.dataSteam;
    //'\  }

    /**
     * 添加处理器
     *
     * @param processor    处理器
     * @param dataTemplate 模板
     */
    public void addProcessor(DataStreamProcessor processor, DataTemplate dataTemplate) {
        if (processors.size() > 0) {
            processor.setPreProcessor(processors.get(processors.size() - 1));
            processors.get(processors.size() - 1).setNextProcessor(processor);
        }
        processors.add(processor);
        processor.init(this, dataTemplate);
    }


//    public void source(DataStreamAdapter dataStreamAdapter) {
//        dataStreamThreadPool.execute(new ProcessorTask(dataStreamAdapter));
//    }

    public void match(byte[] dataBuf) {
        LogHelper.info("待处理数据包 " + BytesUtil.byte2HexStr(dataBuf));
//        this.dataStreamCache.pushDataBuff(dataBuf);
//        processors.get(0).stream(this.dataStreamCache);
    }

    /**
     * 处理任务
     */
    private class ProcessorTask implements Runnable {

        DataStreamAdapter dataStreamAdapter;

        ProcessorTask(DataStreamAdapter dataStreamAdapter) {
            this.dataStreamAdapter = dataStreamAdapter;
        }

        @Override
        public void run() {
//            int readIndex = 0;
//            try {
//                byte[] block = dataStreamAdapter.getBlock();
//                if (block.length == 0) {
//                    return;
//                }
//                LogHelper.info(dataStreamAdapter.getAdapterKey() + " 待处理数据包 " + BytesUtil.byte2HexStr(block));
//                dataSteam.dataBuff = block;
//                dataSteam.takecareTemplates = null;
//                dataSteam.dataProcesser = null;
//                processors.get(0).stream(dataStreamAdapter);
//                if (dataSteam.takecareTemplates.state() == TestState.LOOK) {
//                    //数据报文异常,需要抛弃当前包，定位到下一个报文
//                    if (dataStreamAdapter.getWaitingProcessBlocksCount() >= 10) {
//                        LogHelper.info(dataStreamAdapter.getAdapterKey() + " 数据异常 当前处理流程被卡住!!!");
//                        readIndex = dataStreamAdapter.moveToNext(dataSteam.takecareTemplates.agreement());
//                        if (readIndex == 0) {
//                            //找不到下一个包，直接把当前包抛弃
//                            readIndex = block.length;
//                        }
//                        dataStreamAdapter.resetWaitingProcessBlocksCount();
//                        //记录解析异常的报文
//                        byte[] errorDatagram = dataStreamAdapter.getBlock(readIndex);
//                        LogHelper.info(dataStreamAdapter.getAdapterKey() + " 异常报文 " + BytesUtil.byte2HexStr(errorDatagram));
//                    } else {
//                        dataStreamAdapter.addWaitingProcessBlocksCount();
//                    }
//                } else if (dataSteam.takecareTemplates.state() == TestState.MATHCE) {
//                    //匹配到一个模板
//                    LogHelper.info(dataStreamAdapter.getAdapterKey() + " 匹配到一个模板：" + dataSteam.takecareTemplates.getName());
//                    if (dataSteam.dataProcesser != null && dataSteam.dataProcesser.size() > 0) {
//                        for (int i = 0; i < dataSteam.dataProcesser.size(); i++) {
//                            dataSteam.takecareTemplates.bridgeDataProcessor(dataSteam.dataProcesser.get(i), dataStreamAdapter);
//                        }
//                    }
//                    readIndex = dataSteam.takecareTemplates.length();
//                    dataStreamAdapter.resetWaitingProcessBlocksCount();
//                    //LogHelper.info("match ");
//                } else if (dataSteam.takecareTemplates.state() == TestState.UNKNOWN) {
//                    LogHelper.info(dataStreamAdapter.getAdapterKey() + " 未匹配到可用模板：" + dataSteam.takecareTemplates.getName());
//                    readIndex = dataSteam.takecareTemplates.length();
//                    dataStreamAdapter.resetWaitingProcessBlocksCount();
//                } else {
//                    LogHelper.info(dataStreamAdapter.getAdapterKey() + " *********************不可能出现的故障，没有任何模板匹配！*********************");
//                }
//                dataStreamAdapter.readIndex(readIndex);
//                byte[] reminblock = dataStreamAdapter.getBlock();
//                if (reminblock.length > 0) {
//                    LogHelper.info(dataStreamAdapter.getAdapterKey() + " 未处理数据包 " + BytesUtil.byte2HexStr(reminblock));
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//                LogHelper.error(e);
//            } finally {
//                LogHelper.info(dataStreamAdapter.getAdapterKey() + " *********************任务结束！*********************");
//            }
        }
    }
}
