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

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 javafx.util.Pair;

import java.util.*;

public class SubsetGenerator {
    public static Pair<String, TransactionFile> generateSizeSubset(Pair<String, TransactionFile> dataset, Random random, int index) {
            var data = new ArrayList<>(dataset.getValue().getTransactions());
            Collections.shuffle(data,random);
            var startIndex = random.nextInt(0, data.size());
            var endIndex = random.nextInt(startIndex, data.size());
        return new Pair<>(
                dataset.getKey() + index + "_size",
                new TransactionFile(data.subList(startIndex,endIndex))
        );
    }


    public static Pair<String, TransactionFile> generateUniqueSubset(Pair<String, TransactionFile> dataset, Random random, int index) {
        var data = dataset.getValue().getTransactions();
        Set<AdamissObject> uniqueSet = new HashSet<>();
        for (var transaction: data){
            uniqueSet.addAll(transaction.getData());
        }
        var shuffleList = new ArrayList<>(uniqueSet);
        List<AdamissObject> reducedSet = new ArrayList<>();
        if(!shuffleList.isEmpty()) {
            Collections.shuffle(shuffleList, random);
            var startIndex = random.nextInt(0, shuffleList.size());
            var endIndex = random.nextInt(startIndex, shuffleList.size());
            reducedSet = shuffleList.subList(startIndex, endIndex);
        }
        List<Transaction> resultData = new ArrayList<>();
        for(var transaction : data){
            List<AdamissObject> retain = new ArrayList<>(transaction.getData());
            retain.retainAll(reducedSet);
            if(!retain.isEmpty())resultData.add(new Transaction(retain));
        }

        return new Pair<>(
                dataset.getKey() + index + "_unique",
                new TransactionFile(resultData)
        );
    }


    public static Pair<String, TransactionFile> generateLengthSubset(Pair<String, TransactionFile> dataset, Random random, int index) {
        var data = dataset.getValue().getTransactions();
        List<Transaction> resultData = new ArrayList<>();

        for(var transaction : data){

            var objects = new ArrayList<>(transaction.getData());
            var startIndex = random.nextInt(0, objects.size());
            var endIndex = random.nextInt(startIndex, objects.size());

            var sublist = objects.subList(startIndex,endIndex);
            if(!sublist.isEmpty())
                resultData.add(new Transaction(sublist));
        }

        return new Pair<>(
                dataset.getKey() + index + "_length",
                new TransactionFile(resultData)
        );
    }


    public static Pair<String, TransactionFile> generateCombinedSubset(Pair<String, TransactionFile> dataset, Random random, int index) {
        var sized = generateSizeSubset(dataset,random,index);
        var uniqued = generateUniqueSubset(sized,random,index);
        return new Pair<>(
                dataset.getKey() + index + "_combined",
                generateLengthSubset(uniqued,random,index).getValue());
    }
}
