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


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 cz.muni.disa.adamiss.se.operators.GSP;

import java.util.*;

public class BitMap {
    private Map<List<AdamissObject>, BitSet> bitMap = new HashMap<>();

    public void apply(TransactionFile file, int minsup){
        List<Transaction> transactions = file.getTransactions();
        int max = 0;
        for (Transaction t: transactions){
            if(max< t.getData().size()){
                max = t.getData().size();
            }
        }
        GSP gsp = new GSP();
        Map<List<AdamissObject>, Integer> result = gsp.get1set(file, minsup);
        Set<List<AdamissObject>> list = result.keySet();
        int transactionIndex = 0;
        for (Transaction t: transactions){
            List<AdamissObject> transaction = t.getData();
            for(int i = 0; i<transaction.size(); i++){
                AdamissObject o = transaction.get(Math.toIntExact(i));

                List<AdamissObject> pattern = new ArrayList<>();
                pattern.add(o);
                if(list.contains(pattern)) {
                    if (!bitMap.containsKey(pattern)) {
                        BitSet set = new BitSet(transactions.size() * max + transactions.size());
                        bitMap.put(pattern, set);
                    }
                    bitMap.get(pattern).flip(transactionIndex * (max + 1) + i);
                }
            }
            transactionIndex++;
        }
    }

    public Map<List<AdamissObject>, BitSet> getBitMap() {
        return bitMap;
    }

    public static String toBinaryString(BitSet bs) {
        StringBuilder sb = new StringBuilder(bs.length());
        for (int i = bs.length() - 1; i >= 0; i--)
            sb.append(bs.get(i) ? 1 : 0);
        return sb.toString();
    }
}
