package org.algorithm.factory;

import org.algorithm.core.AlgorithmExecutor;
import org.algorithm.core.bayes.AlgorithmBayesExecutor;
import org.algorithm.core.neural.*;
import org.algorithm.util.AlgorithmClassify;

/**
 * @Auther: fyeman
 * @Date: 2018/7/19/019 10:27
 * @Description:
 */
public class AlgorithmFactory {
    private static AlgorithmBayesExecutor algorithmBayesExecutorInstance = null;

    private static AlgorithmNeuralExecutor algorithmNeuralExecutorInstance = null;

    private static DiagnosisPredictExecutor outpatientExecutorInstance = null;

    private static SymptomPredictExecutor symptomPredictExcutorInstance = null;

    private static VitalPredictExecutor vitalPredictExcutorInstance = null;

    private static PacsPredictExecutor pacsPredictExcutorInstance = null;

    private static LisPredictExecutor lisPredictExcutorInstance = null;

    private static DiagnosisToSymptomExecutor diagnosisToSymptomExecutorInstance = null;

    private static DiagnosisToVitalExecutor diagnosisToVitalExecutorInstance = null;

    private static DiagnosisToLisExecutor diagnosisToLisExecutorInstance = null;

    private static DiagnosisToPacsExecutor diagnosisToPacsExecutorInstance = null;

    public static AlgorithmExecutor getInstance(AlgorithmClassify classify) {
        try {
            switch (classify) {
                case NEURAL:
                    algorithmNeuralExecutorInstance = (AlgorithmNeuralExecutor) create(algorithmNeuralExecutorInstance, AlgorithmNeuralExecutor.class);
                    return algorithmNeuralExecutorInstance;
                case BAYES:
                    algorithmBayesExecutorInstance = (AlgorithmBayesExecutor) create(algorithmBayesExecutorInstance, AlgorithmBayesExecutor.class);
                    return algorithmBayesExecutorInstance;
                case NEURAL_DIAG:
                    outpatientExecutorInstance = (DiagnosisPredictExecutor) create(outpatientExecutorInstance, DiagnosisPredictExecutor.class);
                    return outpatientExecutorInstance;
                case NEURAL_SYMPTOM:
                    symptomPredictExcutorInstance = (SymptomPredictExecutor) create(symptomPredictExcutorInstance, SymptomPredictExecutor.class);
                    return symptomPredictExcutorInstance;
                case NEURAL_VITAL:
                    vitalPredictExcutorInstance = (VitalPredictExecutor) create(vitalPredictExcutorInstance, VitalPredictExecutor.class);
                    return vitalPredictExcutorInstance;
                case NEURAL_LIS:
                    lisPredictExcutorInstance = (LisPredictExecutor) create(lisPredictExcutorInstance, LisPredictExecutor.class);
                    return lisPredictExcutorInstance;
                case NEURAL_PACS:
                    pacsPredictExcutorInstance = (PacsPredictExecutor) create(pacsPredictExcutorInstance, PacsPredictExecutor.class);
                    return pacsPredictExcutorInstance;
                case NEURAL_DIAG_SYMPTOM:
                    diagnosisToSymptomExecutorInstance = (DiagnosisToSymptomExecutor) create(diagnosisToSymptomExecutorInstance, DiagnosisToSymptomExecutor.class);
                    return diagnosisToSymptomExecutorInstance;
                case NEURAL_DIAG_VITAL:
                    diagnosisToVitalExecutorInstance = (DiagnosisToVitalExecutor) create(diagnosisToVitalExecutorInstance, DiagnosisToVitalExecutor.class);
                    return diagnosisToVitalExecutorInstance;
                case NEURAL_DIAG_LIS:
                    diagnosisToLisExecutorInstance = (DiagnosisToLisExecutor) create(diagnosisToLisExecutorInstance, DiagnosisToLisExecutor.class);
                    return diagnosisToLisExecutorInstance;
                case NEURAL_DIAG_PACS:
                    diagnosisToPacsExecutorInstance = (DiagnosisToPacsExecutor) create(diagnosisToPacsExecutorInstance, DiagnosisToPacsExecutor.class);
                    return diagnosisToPacsExecutorInstance;
            }
        } catch (InstantiationException inst) {
            inst.printStackTrace();
        } catch (IllegalAccessException ille) {
            ille.printStackTrace();
        }
        return null;
    }

    private static Object create(Object obj, Class cls) throws InstantiationException, IllegalAccessException {
        if (obj == null) {
            synchronized (cls) {
                obj = cls.newInstance();
            }
        }
        return obj;
    }
}
