package org.diagbot.bigdata.work;

import org.algorithm.core.AlgorithmExecutor;
import org.algorithm.factory.AlgorithmFactory;
import org.algorithm.util.AlgorithmClassify;
import org.diagbot.common.push.bean.FeatureRate;
import org.diagbot.common.push.bean.ResponseData;
import org.diagbot.common.push.bean.SearchData;
import org.diagbot.common.push.naivebayes.factory.AlgorithmNaiveBayesFactory;
import org.diagbot.nlp.feature.FeatureType;
import org.diagbot.nlp.util.Constants;
import org.diagbot.nlp.util.NlpCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @ClassName org.diagbot.bigdata.work.AlgorithmCore
 * @Description TODO
 * @Author fyeman
 * @Date 2019/1/16/016 17:01
 * @Version 1.0
 **/
public class AlgorithmCore {
    Logger logger = LoggerFactory.getLogger(AlgorithmCore.class);

    public ResponseData algorithm(HttpServletRequest request, SearchData searchData, ResponseData responseData) throws Exception {
        //录入文本处理，包括提取特征、推送类型转换等
        BigDataParamsProxy paramsDataProxy = new BigDataParamsProxy();
        logger.info("页面文本信息：" + searchData.getSymptom());
        paramsDataProxy.createSearchData(searchData);
        //对象拷贝至BigDataSearchData处理
        BigDataSearchData bigDataSearchData = new BigDataSearchData();
        BeanUtils.copyProperties(searchData, bigDataSearchData);
        //featureType转算法模型类别
        bigDataSearchData.setAlgorithmClassify(paramsDataProxy.createAlgorithmClassify(searchData.getSysCode(), searchData.getFeatureTypes(), searchData));

        responseData.setInputs(bigDataSearchData.getInputs());
        //推送模型类型集合
        AlgorithmClassify[] classifies = bigDataSearchData.getAlgorithmClassify();
        String[] featureTypes = bigDataSearchData.getFeatureTypes();
        //推送结果处理
        ResultDataProxy resultDataProxy = new ResultDataProxy();
        for (int i = 0; i < classifies.length; i++) {
            if (classifies[i] == null) {
                continue;
            }
            Map<String, Float> featuresMap = null;
            AlgorithmExecutor executor = null;
            switch (searchData.getAlgorithmType() == null ? 1 : searchData.getAlgorithmType()) {
                case 1: //机器学习算法推理
                    executor = AlgorithmFactory.getInstance(classifies[i]);
                    break;
                case 2: //朴素贝叶斯算法推理
                    if (FeatureType.parse(featureTypes[i]) == FeatureType.DIAG) {
                        executor = AlgorithmNaiveBayesFactory.getInstance();
                    }
                    break;
                default:
                    executor = AlgorithmFactory.getInstance(classifies[i]);
            }

            if (executor != null) {
                featuresMap = executor.execute(bigDataSearchData.getInputs());;
            } else {
                continue;
            }
            List<Map.Entry<String, Float>> featuresOrderList = null;
            if (featuresMap == null) {
                featuresOrderList = new ArrayList<Map.Entry<String, Float>>();
            } else {
                //同义词转化
                featuresMap = resultDataProxy.synonymConvert(request, featuresMap, featureTypes[i]);
                //推送项合并---针对症状
                if (Constants.feature_type_symptom.equals(searchData.getFeatureTypes()[i])) {
                    featuresMap = resultDataProxy.mapAdd(featuresMap, NlpCache.getStandard_info_push_map(), true);
                }
                //按模型计算的概率排序
                featuresOrderList = new ArrayList<Map.Entry<String, Float>>(featuresMap.entrySet());
                Collections.sort(featuresOrderList, new Comparator<Map.Entry<String, Float>>() {
                    public int compare(Map.Entry<String, Float> o1, Map.Entry<String, Float> o2) {
                        if (o2.getValue() - o1.getValue() > 0) {
                            return 1;
                        } else if (o2.getValue() - o1.getValue() < 0) {
                            return -1;
                        } else {
                            return 0;
                        }
                    }
                });
            }
            List<FeatureRate> featureRates = resultDataProxy.proxy(request, bigDataSearchData, featuresOrderList, featureTypes[i]);


            switch (FeatureType.parse(featureTypes[i])) {
                case SYMPTOM:
                    responseData.setSymptom(featureRates);
                    break;
                case DIAG:
                    responseData.setDis(featureRates);
                    break;
                case VITAL:
                    responseData.setVitals(featureRates);
                    break;
                case LIS:
                    responseData.setLabs(featureRates);
                    break;
                case PACS:
                    responseData.setPacs(featureRates);
                    break;
                case HISTORY:
                    responseData.setHistory(featureRates);
                    break;
            }
        }
        return responseData;
    }
}
