package org.algorithm.core.bayes;

import org.algorithm.core.AlgorithmExecutor;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: fyeman
 * @Date: 2018/7/19/019 11:21
 * @Description:
 */
public class AlgorithmBayesExecutor extends AlgorithmExecutor {
    private Map<String, List<String>> rdnFeaturesMap = null;

    private List<String> symptomsList = null;

    /**每个特征在文档中出现计数情况*/
    private Map<String, Float> allFeatureCntMap = new HashMap<>(10, 0.8f);
    /**录入条件特征在文档中出现的情况*/
    private Map<String, Float> searchFeatureCntMap = new HashMap<>(10, 0.8f);
    /**总文档计数*/
    private int rdnCnt = 0;

    public Map<String, Float> start(HttpServletRequest request, String[] symptoms) {
        this.featureThreshold(rdnFeaturesMap, symptoms);

        Map<String, Float> result = new HashMap<String, Float>();

        //计算贝叶斯分母 p_s = P(S1,S2|D1) + P(S1,S2|D2) + P(S1,S2|D3) ......        (p_d * p_s_i) / p_s
        float p_s = 0.0f;
        float p_d = 0.0f;
        float p_s_i = 0.0f;
        for (Map.Entry<String, Float> entry : searchFeatureCntMap.entrySet()) {
            p_d = allFeatureCntMap.get(entry.getKey()) / rdnCnt;
            p_s_i = entry.getValue() / allFeatureCntMap.get(entry.getKey());
            p_s += p_d * p_s_i;
        }

        for (Map.Entry<String, Float> entry : searchFeatureCntMap.entrySet()) {
            p_d = allFeatureCntMap.get(entry.getKey()) / rdnCnt;
            p_s_i = entry.getValue() / allFeatureCntMap.get(entry.getKey());
            result.put(entry.getKey(), (p_d * p_s_i) / p_s);
        }
        return result;
    }

    private void featureThreshold(Map<String, List<String>> rdnMap, String[] symptoms) {
        this.rdnCnt = rdnMap.size();

        List<String> featuresList = null;
        for (Map.Entry<String, List<String>> entry : rdnMap.entrySet()) {
            featuresList = rdnMap.get(entry.getKey());
            /**保存特征出现的文档数*/
            this.count(this.allFeatureCntMap, featuresList);

            if (findFeature(entry.getKey(), symptoms)) {
                this.count(searchFeatureCntMap, featuresList);
            }
        }
    }


    public boolean findFeature(String rdn, String[] symptoms) {
        //入参有症状信息，必须包含入参中所有症状信息的文档才计算
        if (!matchFeatures(rdnFeaturesMap, symptomsList, symptoms, rdn)) {
            return false;
        }
        return true;
    }

    private boolean matchFeatures(Map<String, List<String>> featuresMap, List<String> docFeaturesList, String[] args, String rdn) {
        if (args != null && args.length > 0) {
            docFeaturesList = featuresMap.get(rdn);
            if (docFeaturesList == null || docFeaturesList.size() == 0) {
                return false;
            } else {
                //主症状不相同
                if (args.length > 0 && !args[0].equals(docFeaturesList.get(0))) {
                    return false;
                }
                for (String arg : args) {
                    if (arg != null && !docFeaturesList.contains(arg)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private void count(Map<String, Float> cntMap, List<String> featuresList) {
        for (String feature : featuresList) {
            if (cntMap.get(feature) == null) {
                cntMap.put(feature, 1f);
            } else {
                cntMap.put(feature, cntMap.get(feature) + 1);
            }
        }
    }

    public Map<String, Float> execute(Map<String, Map<String, String>> inputs) {
        return null;
    }

    public void setRdnFeaturesMap(Map<String, List<String>> rdnFeaturesMap) {
        this.rdnFeaturesMap = rdnFeaturesMap;
    }
}
