package cz.muni.disa.adamiss.se.helper;


import cz.muni.disa.adamiss.core.common.enums.ParameterName;
import cz.muni.disa.adamiss.core.objects.AdamissObject;
import cz.muni.disa.adamiss.core.objects.Transaction;
import cz.muni.disa.adamiss.core.objects.TransactionFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Helper {
    /**
     * Increase support of sequence by 1
     * @param patterns map of frequent sequencies and their support
     * @param key sequence which support is to be increased
     */
    public static void increaseSup(Map<List<AdamissObject>, Integer> patterns, List<AdamissObject> key){
        int count = 0;
        if(patterns.containsKey(key)){
            count = patterns.get(key);
        }
        patterns.put(key, count + 1);
    }

    public static void increaseSupBy(Map<List<AdamissObject>, Integer> patterns, List<AdamissObject> key, int sup){
        int count = 0;
        if(patterns.containsKey(key)){
            count = patterns.get(key);
        }
        patterns.put(key, count + sup);
    }

    /**
     * remove all sequencies which support is lesser than mining treshold
     * @param patterns map of frequent sequencies and their support
     * @param minSup mining treshold
     */
    public static void removeInfrequent(Map<List<AdamissObject>, Integer> patterns, Integer minSup){
        patterns.values().removeIf(value -> value.compareTo(minSup) < 0);
    }

    /**
     * Print all mined frequent sequencies and their support
     * @param patterns map of mined sequencies and their support
     */
    public static void printPatterns(Map<List<AdamissObject>, Integer> patterns){
        for (Map.Entry<List<AdamissObject>, Integer> entry : patterns.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue().toString());
        }
    }

    public static void printFile(TransactionFile file){
        List<Transaction> transactions = file.getTransactions();
        for(Transaction t: transactions){
            List<AdamissObject> list = t.getData();
            System.out.println(list);
        }
    }

    public static TransactionFile getTransactionFileFromResults(Map<List<AdamissObject>, Integer> results){
        List<Transaction> transactions = new ArrayList<>();
        for(Map.Entry<List<AdamissObject>, Integer> sequence: results.entrySet()){
            Map<String, Object> attrs = new HashMap<>();
            attrs.put(ParameterName.frequency.toString(), sequence.getValue());
            transactions.add(new Transaction(sequence.getKey(), attrs));
        }
        return new TransactionFile(transactions);
    }

    public static Map<AdamissObject, Integer> getFrequency(TransactionFile transactionFile){
        Map<AdamissObject, Integer> result = new HashMap<>();
        for(Transaction transaction : transactionFile.getTransactions()){
            for (AdamissObject o : transaction.getData()){
                increaseItemSupBy(result, o, 1);
            }
        }
        return result;
    }

    public static void increaseItemSupBy(Map<AdamissObject, Integer> itemMap, AdamissObject item, int sup){
        int count = 0;
        if(itemMap.containsKey(item)){
            count = itemMap.get(item);
        }
        itemMap.put(item, count + sup);
    }
}
