package edu.ntnu.idi.goldfish;

import edu.ntnu.idi.goldfish.configurations.Config;
import edu.ntnu.idi.goldfish.configurations.Lynx;
import edu.ntnu.idi.goldfish.preprocessors.PreprocessorClassifier;
import edu.ntnu.idi.goldfish.preprocessors.PreprocessorClustering;
import edu.ntnu.idi.goldfish.preprocessors.PreprocessorMLR;
import edu.ntnu.idi.goldfish.preprocessors.PreprocessorPuddis;
import edu.ntnu.idi.goldfish.preprocessors.PreprocessorPuddis.PredMethod;
import org.apache.commons.lang3.StringUtils;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.functions.SMOreg;

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

import static edu.ntnu.idi.goldfish.DataSet.*;

public class Main {

    public static DataSet set;
	
	// disable Mahout logging output
	static {
		 System.setProperty("org.apache.commons.logging.Log",
		 "org.apache.commons.logging.impl.NoOpLog");
	}

	public static void main(String[] args) throws Exception {

        List<Config> configs = new ArrayList<>();
        ResultList results = new ResultList();

        /***********************************************************************************/
        // Baseline


        Config baseLine = new Lynx()
                .set("name", "baseline")
                .set("model", yowBaseline.getModel())
                .set("average", 10);

        configs.add(baseLine);
        /***********************************************************************************/
        // PreprocessorPuddis

        {
            Config puddis = new Lynx()
                    .set("name", "puddis")
                    .set("model", yowSMImplicit.getModel())
                    .set("preprocessor", PreprocessorPuddis.class)
                    .set("average", 10);

            Config conf;
            for (int minT = 15000; minT <= 30000; minT += 5000) {
                for (double corrLimit = 0.4; corrLimit <= 0.8; corrLimit += 0.1) {
                    for (PredMethod method : PredMethod.values()) {
                        conf = puddis.clone()
                                .set("minTimeOnPage", minT)
                                .set("correlationLimit", corrLimit)
                                .set("predictionMethod", method);

                        configs.add(conf);
                    }
                }
            }
        }

        /***********************************************************************************/
        // PreprocessorClassifier

        Config classifiers = new Lynx()
                .set("name", "classifier")
                .set("model", yowImplicit.getModel())
                .set("preprocessor", PreprocessorClassifier.class)
                .set("average", 10);

        List<Class> classes = Arrays.asList(NaiveBayes.class, SMOreg.class);
        classes.stream().forEach(c ->
            configs.add(classifiers.clone().set("name", c.getSimpleName()).set("classifier", c))
        );

        /***********************************************************************************/
        // PreprocessorClustering

        {

            Config clustering = new Lynx()
                    .set("name", "clustering")
                    .set("model", yowImplicit.getModel())
                    .set("preprocessor", PreprocessorClustering.class)
                    .set("average", 10);

            Config conf;
            for(PreprocessorClustering.Clusterer clusterer : PreprocessorClustering.Clusterer.values()) {
                for(PreprocessorClustering.ClusterDataset dataset : PreprocessorClustering.ClusterDataset.values()) {
                    conf = clustering.clone()
                            .set("clusterer", clusterer)
                            .set("clusterDataset", dataset);
                    configs.add(conf);
                }
            }
        }

        /***********************************************************************************/
        // PreprocessorMLR

        {
            Config mlr = new Lynx()
                    .set("name", "MLR")
                    .set("model", yowImplicit.getModel())
                    .set("preprocessor", PreprocessorMLR.class)
                    .set("average", 10);

            Config conf;
            for (int i = 1; i <= 3; i++) {
                conf = mlr.clone()
                        .set("numberOfIndependentVariables", i);
                configs.add(conf);
            }
        }

        /***********************************************************************************/

        Columns columns = Columns.getPrintFormats("name", "average", "RMSE", "evalTime", "minTimeOnPage", "correlationLimit",
                "predictionMethod", "clusterer", "clusterDataset", "numberOfIndependentVariables", "classifier");
        results.setColumns(columns);

		StopWatch.start("total evaluation");
        System.out.format("Starting evaluation of %d configurations \n", configs.size());
        Evaluator.evaluate(configs, results, res -> System.out.println(res.toString(columns)));

//        results.print();
        System.out.println(StringUtils.repeat("=", 190));
//        results.printSummary();

        System.out.format("Evaluated %d configurations in %s \n", configs.size(), StopWatch.str("total evaluation"));
        results.save();

    }
}

@@ -1350,35 +1350,38 @@
 et(%22average%22, 10
+000
 );%0A
-
 %0A        configs
@@ -1770,32 +1770,35 @@
 et(%22average%22, 10
+000
 );%0A%0A            
@@ -2824,16 +2824,18 @@
 class);%0A
+//
         
@@ -2864,16 +2864,18 @@
 ch(c -%3E%0A
+//
         
@@ -2963,16 +2963,18 @@
 r%22, c))%0A
+//
         
@@ -3791,16 +3791,18 @@
 taset);%0A
+//
         
@@ -3824,32 +3824,32 @@
 figs.add(conf);%0A
-
                 
@@ -4235,32 +4235,35 @@
 et(%22average%22, 10
+000
 );%0A%0A            
@@ -4698,32 +4698,16 @@
 nLimit%22,
-%0A               
  %22predic
@@ -4722,39 +4722,8 @@
 od%22,
- %22clusterer%22, %22clusterDataset%22,
  %22nu
@@ -4749,30 +4749,16 @@
 riables%22
-, %22classifier%22
 );%0A     
@@ -5101,18 +5101,16 @@
  190));%0A
-//
         
@@ -5129,24 +5129,24 @@
 tSummary();%0A
+
 %0A        Sys
@@ -5248,24 +5248,24 @@
 luation%22));%0A
-
         resu
@@ -5273,16 +5273,166 @@
 ts.save(
+Columns.getSaveFormats(%22name%22, %22average%22, %22RMSE%22, %22evalTime%22, %22minTimeOnPage%22, %22correlationLimit%22, %22predictionMethod%22, %22numberOfIndependentVariables%22)
 );%0A%0A    

Prepare evaluation