package edu.ntnu.idi.goldfish;

import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;

public class ResultList extends ArrayList<Result> {

    Columns columns;

	public ResultList() {

	}

    public void setColumns(String... properties) {
        columns = Columns.getPrintFormats(properties);
    }

    public void print() {
        forEach(r -> System.out.println(r.toString(columns)));
    }

    public void printSummary() {
        System.out.println(getTotal().toString(columns));
        System.out.println(getAverage().toString(columns));
    }



	public void print(String... properties) {
        Columns columns = Columns.getPrintFormats(properties);
        forEach(r -> System.out.println(r.toString(columns)));
    }

    public void save() throws IOException {
        save(columns);
    }

    public void save(String... properties) throws IOException {
        Columns columns = Columns.getSaveFormats(properties);
        save(columns);
    }
	
	public String toTSV(Columns columns) {
		String out = "";
		out += StringUtils.join(columns.keySet(), "\t") +"\n";
        out += getTotal()+"\n";
        out += getAverage()+"\n";
		for (Result res : this) {
			out += res.toTSV(columns)+"\n";
		}
		return out;
	}
	

	public void save(Columns columns) throws IOException {
        String output = toTSV(columns);
        String dateTime = String.format("%1$tY-%1$tm-%1$td-%1$tH%1$tM%1$tS", new Date());
        String fileName = String.format("results/%s-%s%s.tsv", dateTime, "", "");
        File file = new File(fileName);
        Writer writer = new BufferedWriter(new FileWriter(file));
        writer.write(output);
        System.out.println("Saved to file: " + fileName);
    }

    public Result getTotal() {
        String[] properties = new String[]{"RMSE", "AAD", "precision", "recall", "buildTime", "recTime", "evalTime"};

        // create result object
        Result total = new Result().set("name", "# TOTAL");

        // ensure we have a few results
        if(size() == 0) return total;

        // for each property, calculate totals and set them on total object
        for(String property : properties) {
            Result first = get(0);
            if (first.containsKey(property)) {
                double sum = 0;
                for (Result res : this) {
                    Number value = res.get(property);
                    sum += value.doubleValue();
                }
                total.set(property, sum);
            }
        }
        return total;
    }

    public Result getAverage() {
        String[] properties = new String[]{"RMSE", "AAD", "precision", "recall", "buildTime", "recTime", "evalTime"};
        Result total = getTotal();
        Result average = new Result().set("name", "# AVERAGE");
        int N = size();

        for(String property : properties) {
            if(total.containsKey(property)) {
                // the returned type can be Double or Long, so we need to check in order to cast to the right primitive
                // too bad java generics doesn't support primitives
                Number sum = total.get(property);
                average.set(property, (sum.doubleValue() / N));
            }

        }
        return average;
    }

}

@@ -244,16 +244,188 @@
  %7B%0A%0A%09%7D%0A%0A
+    public synchronized boolean add(Result res) %7B%0A        return super.add(res);%0A    %7D%0A%0A    public void setColumns(Columns columns)%7B%0A        this.columns = columns;%0A    %7D%0A%0A
     publ
@@ -475,26 +475,27 @@
         
-c
+setC
 olumns
- = 
+(
 Columns.
@@ -517,24 +517,25 @@
 (properties)
+)
 ;%0A    %7D%0A%0A   
@@ -967,238 +967,8 @@
  %7D%0A%0A
-    public void save() throws IOException %7B%0A        save(columns);%0A    %7D%0A%0A    public void save(String... properties) throws IOException %7B%0A        Columns columns = Columns.getSaveFormats(properties);%0A        save(columns);%0A    %7D%0A%09
 %0A%09pu
@@ -1105,16 +1105,31 @@
 tTotal()
+.toTSV(columns)
 +%22%5Cn%22;%0A 
@@ -1154,16 +1154,31 @@
 verage()
+.toTSV(columns)
 +%22%5Cn%22;%0A%09
@@ -1243,18 +1243,24 @@
 n%22;%0A%09%09%7D%0A
-%09%09
+        
 return o
@@ -1270,12 +1270,89 @@
 %0A%09%7D%0A
-%09%0A%0A%09
+%0A%0A    public void save() throws IOException %7B%0A        save(columns);%0A    %7D%0A%0A%0A    
 publ
@@ -1750,16 +1750,40 @@
 utput);%0A
+        writer.close();%0A
         

Fix saving issues in ResultList