package cz.muni.disa.adamiss.se;

import cz.muni.disa.adamiss.core.common.enums.ParameterName;
import cz.muni.disa.adamiss.core.objects.Transaction;
import cz.muni.disa.adamiss.core.objects.TransactionFile;
import cz.muni.disa.adamiss.se.operators.GSP;
import cz.muni.disa.adamiss.se.operators.PrefixSpan;
import cz.muni.disa.adamiss.se.operators.Spade;
import cz.muni.disa.adamiss.se.operators.Spam;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static cz.muni.disa.adamiss.se.loader.DatasetLoader.*;

public class Main {

    public static void main(String[] args) {
        String dataset;
        int threshold;
        dataset = args[0];
        threshold = Integer.parseInt(args[1]);

        long startTime;
        PrefixSpan prefixSpan = new PrefixSpan();
        GSP gsp = new GSP();
        Spade spade = new Spade();
        Spam spam = new Spam();

        Map<String, Object> params = new HashMap<>();
        params.put("miningThreshold", threshold);

        TransactionFile data = loadDataset(dataset);

        System.out.println("PrefixSpan");
        startTime = System.currentTimeMillis();
        TransactionFile prefFile = prefixSpan.apply(data,params);
        long prefixTime = System.currentTimeMillis() - startTime;

        System.out.println("Spam");
        startTime = System.currentTimeMillis();
        TransactionFile spamFile = spam.apply(data,params);
        long spamTime = System.currentTimeMillis() - startTime;


        System.out.println("GSP");
        startTime = System.currentTimeMillis();
        TransactionFile gspFile = gsp.apply(data,params);
        long gspTime = System.currentTimeMillis() - startTime;

//
        System.out.println("Spade");
        startTime = System.currentTimeMillis();
        TransactionFile spadeFile = spade.apply(data,params);
        long spadeTime = System.currentTimeMillis() - startTime;

        //saveTransactionFileTxt(prefFile, "PrefixSpan", threshold, dataset, prefixTime);
        //saveTransactionFileTxt(spadeFile, "Spade", threshold, dataset, spadeTime);
        //saveTransactionFileTxt(gspFile, "GSP", threshold, dataset, gspTime);
        //saveTransactionFileTxt(spamFile, "Spam", threshold, dataset, spamTime);

    }

    public static void getDatabaseStats(TransactionFile file){
        System.out.println("Nunber of Sequences: " +file.getTransactions().size());
        int max = 0;
        int min = 1000;
        long len = 0;
        double avg = 0;
        for(Transaction t:file.getTransactions()){
            len += t.getData().size();
            if(t.getData().size()<min){
                min = t.getData().size();
            }
            if(t.getData().size()>max){
                max = t.getData().size();
            }
        }
        avg = (double) len/file.getTransactions().size();
        System.out.println("Longest: " + max);
        System.out.println("Shortest: " + min);
        System.out.println("avg: " + avg);


    }


    public static void saveTransactionFileTxt(TransactionFile file, String algName, int threshold, String dataset, long time){
        File outFile = new File(algName + "_" + dataset +"_" + threshold + ".txt");
        FileWriter fr = null;

        try {
            String data = "";
            fr = new FileWriter(outFile);
            int max = 0;
            for(Transaction t:file.getTransactions()){
                if(t.getData().size()> max){
                    max = t.getData().size();
                }
                String line = t.getData().toString() + ": " + t.getAttributes().get(ParameterName.frequency.toString()) + System.lineSeparator();
                data+=line;
            }
            fr.write("Time elapsed: " + time + System.lineSeparator());
            fr.write("Total number of mined sequences: " + file.getTransactions().size() + System.lineSeparator());
            fr.write("Length of longest sequence: " + max + System.lineSeparator());
            fr.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void getResultStats(TransactionFile file){
        int longer1 = 0 , longer3 = 0;
        for(Transaction t: file.getTransactions()){
            if(t.getData().size()>1){
                longer1++;
            }
            if(t.getData().size()>3){
                longer3++;
            }
        }
        System.out.println("Longer than 1: " +longer1);
        System.out.println("Longer than 3: " +longer3);

    }
}
