package org.diagbot.nlp.relation.analyze;

import org.algorithm.core.cnn.AlgorithmCNNExecutor;
import org.algorithm.core.cnn.entity.Lemma;
import org.algorithm.core.cnn.entity.Triad;
import org.algorithm.core.cnn.model.impl.RelationExtractionModelFromHttp;
import org.algorithm.core.cnn.model.impl.RelationExtractionModelImpl;
import org.diagbot.nlp.feature.FeatureType;
import org.diagbot.nlp.participle.ParticipleUtil;
import org.diagbot.nlp.participle.word.Lexeme;
import org.diagbot.nlp.participle.word.LexemePath;
import org.diagbot.nlp.relation.extract.*;
import org.diagbot.nlp.relation.util.OutputInfo;
import org.diagbot.nlp.relation.util.LemmaUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName org.diagbot.nlp.relation.RelationAnalyze
 * @Description 关系抽取入口
 * @Author fyeman
 * @Date 2019/1/18/018 14:36
 * @Version 1.0
 **/
public class RelationAnalyze {
    public List<OutputInfo> analyze(String content, FeatureType featureType) throws Exception {
        String[] part_contents = content.split("\\。|\\；\\\r|\\\n|\\;");

        List<OutputInfo> outputInfos = new ArrayList<>();

        LemmaUtil lemmaUtil = new LemmaUtil();
        for (String part_content : part_contents) {
            LexemePath<Lexeme> lexemes = ParticipleUtil.participle(part_content, true);
            //分词结果转词元结构，只提取有词性信息，因为部分特征信息未在三元组中，所以需要把分词结果也一并传入
            List<Lemma> lemmaParticiple = lemmaUtil.lexemeToTriadLemma(lexemes);
            //调用CNN模型
            long start = System.currentTimeMillis();
            //删除不作为训练样本集
            List<Triad> triads = lemmaUtil.findPairTraids(lemmaParticiple);
            AlgorithmCNNExecutor executor = new RelationExtractionModelFromHttp();
            triads = executor.execute(part_content, triads);
            //模型返回的三元组转树形结构
            List<Lemma> lemmaTree = lemmaUtil.traidToTree(triads, featureType);
            long end = System.currentTimeMillis();
            System.out.println("end - start : " + (end - start));
            OutputInfo outputInfo = new OutputInfo();
            switch (featureType) {
                case SYMPTOM:
                    this.lemmaPresentExtract(outputInfo, lemmaTree, lemmaParticiple);
                    this.lemmaVitalExtract(outputInfo, lemmaTree, lemmaParticiple);
                    this.lemmaLisExtract(outputInfo, lemmaTree, lemmaParticiple);
                    this.lemmaPacsExtract(outputInfo, lemmaTree, lemmaParticiple);
                    this.lemmaTreatExtract(outputInfo, lemmaTree, lemmaParticiple);
            }
            if (outputInfo != null) {
                outputInfos.add(outputInfo);
            }
        }
        return outputInfos;
    }

    public OutputInfo lemmaPresentExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
        //现病史症状信息提取
        PresentExtract presentExtract = new PresentExtract();
        outputInfo = presentExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
        return outputInfo;
    }

    /**
     * 体征特征提取
     * @param outputInfo
     * @param lemmaTree
     * @param lemmaParticiple
     * @return
     */
    public OutputInfo lemmaVitalExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
        VitalExtract vitalExtract = new VitalExtract();
        outputInfo = vitalExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
        return outputInfo;
    }

    /**
     * 化验特征提取
     * @param outputInfo
     * @param lemmaTree
     * @param lemmaParticiple
     * @return
     */
    public OutputInfo lemmaLisExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
        LisExtract lisExtract = new LisExtract();
        outputInfo = lisExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
        return outputInfo;
    }

    /**
     * 检查特征提取
     * @param outputInfo
     * @param lemmaTree
     * @param lemmaParticiple
     * @return
     */
    public OutputInfo lemmaPacsExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
        PacsExtract pacsExtract = new PacsExtract();
        outputInfo = pacsExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
        return outputInfo;
    }

    /**
     * 治疗特征提取
     * @param outputInfo
     * @param lemmaTree
     * @param lemmaParticiple
     * @return
     */
    public OutputInfo lemmaTreatExtract(OutputInfo outputInfo, List<Lemma> lemmaTree, List<Lemma> lemmaParticiple) {
        TreatExtract treatExtract = new TreatExtract();
        outputInfo = treatExtract.extract(outputInfo, lemmaTree, lemmaParticiple);
        return outputInfo;
    }
}
