package de.ugoe.cs.crosspare;

import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.security.InvalidParameterException;

public class ConfigurationBuilder {

    private static enum Dataset {MDP, JURECZKO};
    
    private static final String storageFolder = "config/";
    
    public static void main(String[] args) {
        for( Dataset dataset : Dataset.values() ) {
            writeFile("Koshgoftaar2008", dataset);
            writeFile("Watanabe2008", dataset);
            writeFile("Turhan2009", dataset);
            writeFile("CamargoCruz2009", dataset);
            // TODO Liu 2010
            writeFile("Menzies2011", dataset);
            writeFile("Ma2012", dataset);
            writeFile("Peters2012", dataset);
            writeFile("Uchigaki2012", dataset);
            // TODO Canfora 2013 (MODEP)
            writeFile("Peters2013", dataset);
            writeFile("Herbold2013", dataset);
            writeFile("ZHe2013", dataset);
            writeFile("Nam2013", dataset);
            writeFile("Panichella2014", dataset);
            // TODO F.Zhang 2014
            // TODO Mizuno 2014: data not public
            // TODO Ryu 2014
            writeFile("PHe2015", dataset);
            // TODO Peters 2015 (LACE2)
            // TODO Chen 2015
            writeFile("Kawata2015", dataset);
            writeFile("YZhang2015", dataset);
            writeFile("Amasaki2015", dataset);
            // TODO Ryu 2015a
            writeFile("Ryu2015b", dataset);
            // TODO Cao 2015 implementation details missing
            writeFile("Nam2015b", dataset);
            // TODO test
        }
    }
    
    public static void writeFile(String approach, Dataset dataset) {
        FileWriter writer;
        try {
            writer = new FileWriter(storageFolder + dataset.toString() + "-" + approach + ".xml");
            writer.append((String) ConfigurationBuilder.class.getMethod(approach, Dataset.class).invoke(null, dataset));
            writer.flush();
            writer.close();
        }
        catch (IOException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public static void preamble(StringBuilder configFile) {
        configFile.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        configFile.append("<config xmlns=\"experimentconfig\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"experimentconfig experimentconfig.xsd\">\n");
    }
    
    public static void postamble(StringBuilder configFile) {
        configFile.append("</config>");
    }
    
    public static void trainers(StringBuilder configFile) {
        configFile.append(" <trainer name=\"WekaTraining\" param=\"RandomForest weka.classifiers.trees.RandomForest -CVPARAM I 5 25 5\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"C4.5-DTree weka.classifiers.trees.J48 -CVPARAM C 0.1 0.3 5\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"Logistic weka.classifiers.functions.Logistic\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"NeuralNetwork weka.classifiers.functions.MultilayerPerceptron -CVPARAM M 1.5 2.5 3.0 L 0.2 0.4 3.0\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"RBFNetwork weka.classifiers.functions.RBFNetwork -CVPARAM W 0.1 10.0 3.0 L 2.0 18.0 3.0\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"SMORBF weka.classifiers.functions.SMO -K weka.classifiers.functions.supportVector.RBFKernel\" />\n");
    }
    
    public static void trainersBagging(StringBuilder configFile) {
        configFile.append(" <setwisetrainer name=\"WekaBaggingTraining\" param=\"BaggingRandomForest weka.classifiers.trees.RandomForest -CVPARAM I 5 25 5\" />\n");
        configFile.append(" <setwisetrainer name=\"WekaBaggingTraining\" param=\"BaggingC4.5-DTree weka.classifiers.trees.J48 -CVPARAM C 0.1 0.3 5\" />\n");
        configFile.append(" <setwisetrainer name=\"WekaBaggingTraining\" param=\"BaggingLogistic weka.classifiers.functions.Logistic\" />\n");
        configFile.append(" <setwisetrainer name=\"WekaBaggingTraining\" param=\"BaggingNeuralNetwork weka.classifiers.functions.MultilayerPerceptron -CVPARAM M 1.5 2.5 3.0 L 0.2 0.4 3.0\" />\n");
        configFile.append(" <setwisetrainer name=\"WekaBaggingTraining\" param=\"BaggingRBFNetwork weka.classifiers.functions.RBFNetwork -CVPARAM W 0.1 10.0 3.0 L 2.0 18.0 3.0\" />\n");
        configFile.append(" <setwisetrainer name=\"WekaBaggingTraining\" param=\"BaggingSMORBF weka.classifiers.functions.SMO -K weka.classifiers.functions.supportVector.RBFKernel\" />\n");
    }
    
    public static void trainersLocalWhere(StringBuilder configFile) {
        configFile.append(" <trainer name=\"WekaLocalFQTraining\" param=\"LocalRandomForest weka.classifiers.trees.RandomForest -CVPARAM I 5 25 5\" />\n");
        configFile.append(" <trainer name=\"WekaLocalFQTraining\" param=\"LocalC4.5-DTree weka.classifiers.trees.J48 -CVPARAM C 0.1 0.3 5\" />\n");
        configFile.append(" <trainer name=\"WekaLocalFQTraining\" param=\"LocalLogistic weka.classifiers.functions.Logistic\" />\n");
        configFile.append(" <trainer name=\"WekaLocalFQTraining\" param=\"LocalNeuralNetwork weka.classifiers.functions.MultilayerPerceptron -CVPARAM M 1.5 2.5 3.0 L 0.2 0.4 3.0\" />\n");
        configFile.append(" <trainer name=\"WekaLocalFQTraining\" param=\"LocalRBFNetwork weka.classifiers.functions.RBFNetwork -CVPARAM W 0.1 10.0 3.0 L 2.0 18.0 3.0\" />\n");
        configFile.append(" <trainer name=\"WekaLocalFQTraining\" param=\"LocalSMORBF weka.classifiers.functions.SMO -K weka.classifiers.functions.supportVector.RBFKernel\" />\n");
    }
    
    public static void trainersLASER(StringBuilder configFile) {
        configFile.append(" <trainer name=\"WekaLASERTraining\" param=\"LASERRandomForest weka.classifiers.trees.RandomForest -CVPARAM I 5 25 5\" />\n");
        configFile.append(" <trainer name=\"WekaLASERTraining\" param=\"LASERC4.5-DTree weka.classifiers.trees.J48 -CVPARAM C 0.1 0.3 5\" />\n");
        configFile.append(" <trainer name=\"WekaLASERTraining\" param=\"LASERLogistic weka.classifiers.functions.Logistic\" />\n");
        configFile.append(" <trainer name=\"WekaLASERTraining\" param=\"LASERNeuralNetwork weka.classifiers.functions.MultilayerPerceptron -CVPARAM M 1.5 2.5 3.0 L 0.2 0.4 3.0\" />\n");
        configFile.append(" <trainer name=\"WekaLASERTraining\" param=\"LASERRBFNetwork weka.classifiers.functions.RBFNetwork -CVPARAM W 0.1 10.0 3.0 L 2.0 18.0 3.0\" />\n");
        configFile.append(" <trainer name=\"WekaLASERTraining\" param=\"LASERSMORBF weka.classifiers.functions.SMO -K weka.classifiers.functions.supportVector.RBFKernel\" />\n");
    }
        
    public static void dataset(StringBuilder configFile, Dataset dataset) {
        switch (dataset)
        {
            case MDP:
                configFile.append(" <loader name=\"NasaARFFFolderLoader\" datalocation=\"exp-mdp/data\" relative=\"false\"/>\n");
                configFile.append(" <resultsPath path=\"exp-mdp/results\"/>\n");
                break;
            case JURECZKO:
                configFile.append(" <loader name=\"CSVFolderLoader\" datalocation=\"exp-java/data\" relative=\"false\"/>\n");
                configFile.append(" <resultsPath path=\"exp-java/results\"/>\n");
                break;
            default:
                throw new InvalidParameterException("Unknown data set: " + dataset.toString());
        }
    }
    
    public static String Koshgoftaar2008(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainersBagging(configFile);
        
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Watanabe2008(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <setwisepreprocessor name=\"AverageStandardization\" param=\"\" />\n");        
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Turhan2009(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"LogarithmTransform\" param=\"\" />\n");
        configFile.append(" <pointwiseselector name=\"TurhanFilter\" param=\"10\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String CamargoCruz2009(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"LogarithmTransform\" param=\"\" />\n");
        configFile.append(" <preprocessor name=\"MedianAsReference\" param=\"10\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    // TODO Liu 2010
    
    public static String Menzies2011(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        
        trainersLocalWhere(configFile);        
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Ma2012(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"DataGravitation\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Peters2012(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"MORPH\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Uchigaki2012(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        
        configFile.append(" <preprocessor name=\"ZScoreNormalization\" param=\"\" />");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"LogisticEnsemble de.ugoe.cs.cpdp.wekaclassifier.LogisticEnsemble\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    // TODO Canfora 2013 (MODEP)
    
    public static String Peters2013(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"MORPH\" param=\"\" />\n");
        configFile.append(" <pointwiseselector name=\"CLIFF\" param=\"0.10\" />");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Herbold2013(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <setwisepreprocessor name=\"Normalization\" param=\"\" />\n");
        configFile.append(" <setwiseselector name=\"SetWiseEMClusterSelection\" param=\"mean stddev\" />\n");
        configFile.append(" <postprocessor name=\"BiasedWeights\" param=\"0.5\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String ZHe2013(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainersBagging(configFile);
        
        configFile.append(" <setwisepreprocessor name=\"Normalization\" param=\"\" />\n");
        configFile.append(" <setwiseselector name=\"SeparatabilitySelection\" param=\"\" />\n");
        configFile.append(" <setwisepostprocessor name=\"Undersampling\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Nam2013(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"TCAPlusNormalization\" param=\"\" />\n");
        configFile.append(" <postprocessor name=\"TransferComponentAnalysis\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Panichella2014(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        
        configFile.append(" <trainer name=\"WekaTraining\" param=\"LogisticCODEP de.ugoe.cs.cpdp.wekaclassifier.LogisticCODEP\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"BayesNetCODEP de.ugoe.cs.cpdp.wekaclassifier.BayesNetCODEP\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    // TODO F.Zhang 2014
    
    // TODO Mizuno 2014: data not public
    
    // TODO Ryu 2014
    
    public static String PHe2015(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <setwisepreprocessor name=\"LogarithmTransform\" param=\"\" />\n");
        configFile.append(" <setwisepreprocessor name=\"TopMetricFilter\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    // TODO Peters 2015 (LACE2)
    
    // TODO Chen 2015
    
    public static String Kawata2015(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <pointwiseselector name=\"DBSCANFilter\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String YZhang2015(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        
        configFile.append(" <trainer name=\"WekaTraining\" param=\"AVGVote weka.classifiers.meta.Vote -S 1 -B &quot;weka.classifiers.trees.ADTree&quot; -B &quot;weka.classifiers.rules.DecisionTable&quot; -B &quot;weka.classifiers.bayes.BayesNet&quot; -B &quot;weka.classifiers.functions.MultilayerPerceptron&quot; -B &quot;weka.classifiers.functions.RBFNetwork&quot; -R AVG\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"MAXVote weka.classifiers.meta.Vote -S 1 -B &quot;weka.classifiers.trees.ADTree&quot; -B &quot;weka.classifiers.rules.DecisionTable&quot; -B &quot;weka.classifiers.bayes.BayesNet&quot; -B &quot;weka.classifiers.functions.MultilayerPerceptron&quot; -B &quot;weka.classifiers.functions.RBFNetwork&quot; -R MAX\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"BAGGINGC4.5 weka.classifiers.meta.Bagging -P 100 -S 1 -I 10 -W weka.classifiers.trees.J48\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"BAGGINGNaiveBayes weka.classifiers.meta.Bagging -P 100 -S 1 -I 10 -W weka.classifiers.bayes.NaiveBayes\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"BOOSTINGC4.5 weka.classifiers.meta.AdaBoostM1 -P 100 -S 1 -I 10 -W weka.classifiers.trees.J48\" />\n");
        configFile.append(" <trainer name=\"WekaTraining\" param=\"BOOSTINGNaiveBayes weka.classifiers.meta.AdaBoostM1 -P 100 -S 1 -I 10 -W weka.classifiers.bayes.NaiveBayes\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    public static String Amasaki2015(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"LogarithmTransform\" param=\"\" />\n");
        configFile.append(" <preprocessor name=\"SynonymAttributePruning\" param=\"\" />\n");
        configFile.append(" <pointwiseselector name=\"SynonymOutlierRemoval\" param=\"\" />");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    // TODO Amasaki 2015
    
    // TODO Ryu 2015a
    
    public static String Ryu2015b(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainersLASER(configFile);
        
        configFile.append(" <pointwiseselector name=\"MahalanobisOutlierRemoval\" param=\"\" />\n");
        configFile.append(" <pointwiseselector name=\"NeighborhoodFilter\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
    
    // TODO Cao 2015
    
    public static String Nam2015b(Dataset dataset) {
        StringBuilder configFile = new StringBuilder();
        preamble(configFile);
        dataset(configFile, dataset);
        trainers(configFile);
        
        configFile.append(" <preprocessor name=\"CLAMIProcessor\" param=\"\" />\n");
        configFile.append(" <eval name=\"NormalWekaEvaluation\" param=\"\" />\n");
        
        postamble(configFile);
        return configFile.toString();
    }
}
