package org.ts.ddcs.datatemplate;


import lombok.Data;
import org.ts.ddcs.dataStream.DataStreamProcessor;
import org.ts.ddcs.dataprocesser.DataProcesserInterface;
import org.ts.ddcs.filter.DataFilter;
import org.ts.ddcs.tools.ToolHelp;
import org.ts.ddcs.util.BytesUtil;

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

/**
 * created by swp on 2017/8/29
 */
@Data
public class Template {
    /**
     * 关键字
     */
    public byte[] featureKey = null;
    /**
     * 关键字起始位置
     */
    public byte[] featureIndex = null;
    /**
     * 权重，用最远的特征值位置来表示
     */
    public int featureWeight = 0;
    /**
     * 模板类名
     */
    public String dataTemplate = null;
    /**
     * 流处理器类名
     */
    public String streamProcessor = null;
    /**
     * 数据处理器类名
     */
    public LinkedList<String> dataProcessor = new LinkedList<>();
    /**
     * 过滤器
     */
    public LinkedList<String> filter = new LinkedList<>();
    /**
     * 是否可用
     */
    public String enable = null;
    /**
     * 模板名称
     */
    public String templateName;

    private String key;

    public Template(){
        this.key = ToolHelp.randomUUID();
    }


    /**
     * @return
     * @throws NullPointerException
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public synchronized DataTemplateInterface newDataTemplateInstance() throws NullPointerException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (null == this.dataTemplate || this.dataTemplate.length() <= 0) {
            throw new NullPointerException("dataTemplate name is null");
        }
        Class class2 = Class.forName(this.dataTemplate);
        Object obj2 = class2.newInstance();
        if (obj2 instanceof DataTemplateInterface) {
            DataTemplateInterface dataTemplateInterface = (DataTemplateInterface) obj2;
            dataTemplateInterface.setName(this.dataTemplate);
            return dataTemplateInterface;
        } else {
            throw new ClassNotFoundException();
        }
    }


    /**
     * @return
     * @throws NullPointerException
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    List<DataProcesserInterface> newDataProcessorInstance() throws NullPointerException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (null == this.dataProcessor || this.dataProcessor.size() == 0) {
            throw new NullPointerException("dataProcessor name is null");
        }
        List<DataProcesserInterface> processerInterfaceList = new LinkedList<>();
        for (String processor : this.dataProcessor) {
            Class class2 = Class.forName(processor);
            Object obj2 = class2.newInstance();
            if (obj2 instanceof DataProcesserInterface) {
                DataProcesserInterface dataProcesserInterface = (DataProcesserInterface) obj2;
                dataProcesserInterface.setName(processor);
                processerInterfaceList.add(dataProcesserInterface);
            } else {
                throw new ClassNotFoundException();
            }
        }
        return processerInterfaceList;
    }

    DataStreamProcessor newDataStreamProcessorInstance() throws NullPointerException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        if (null == this.streamProcessor || this.streamProcessor.length() <= 0) {
            throw new NullPointerException("streamProcessor name is null");
        }
        Class class2 = Class.forName(this.streamProcessor);
        Object obj2 = class2.newInstance();
        if (obj2 instanceof DataStreamProcessor) {
            DataStreamProcessor dataStreamProcessor = (DataStreamProcessor) obj2;
            return dataStreamProcessor;
        } else {
            throw new ClassNotFoundException();
        }
    }

    LinkedList<DataFilter> createFilterLine() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        LinkedList<DataFilter> fs = new LinkedList<>();
        for (Object o : filter) {
            String name = (String) o;
            Class class2 = Class.forName(name);
            Object obj2 = class2.newInstance();
            if (obj2 instanceof DataFilter) {
                DataFilter dataFilter = (DataFilter) obj2;
                fs.add(dataFilter);
            } else {
                throw new ClassNotFoundException();
            }
        }
        return fs;
    }

    boolean setFeature(String feature) {
        if (null == feature || feature.length() <= 0) {
            return false;
        }
        String exFeture = "*";
        if (exFeture.equals(feature)) {
            this.featureWeight = 9999;
            return true;
        }
        String[] fs = feature.split(":");
        if (fs.length > 0) {
            String max = fs[fs.length - 1];
            String[] vs = max.split("=");
            int maxPos = Integer.parseInt(vs[0]);
            this.featureIndex = new byte[fs.length];
            this.featureKey = new byte[maxPos];
            this.featureWeight = maxPos;
            for (int i = 0; i < fs.length; i++) {
                String[] fa = fs[i].split("=");
                if (fa.length == 2) {
                    int iv = Integer.parseInt(fa[0]) - 1;
                    if (iv < maxPos) {
                        this.featureIndex[i] = (byte) (iv);
                        byte[] value = BytesUtil.hstrToBytes(fa[1]);
                        this.featureKey[iv] = value[0];
                    }
                }
            }
        }
        return true;
    }
}
