package nogui;

import alg.XML_processing;
import data.*;
import gui.GUIController;
import gui.I18N;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.ReadOnlyDoubleWrapper;
import javafx.concurrent.Task;
import javafx.scene.control.Alert;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import util.Tasks;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;

import static gui.GUIController.showAlert;
import static nogui.Utils.*;

public class WordParts {
    public final static Logger logger = LogManager.getLogger(GUIController.class);
    
    public static void wordParts(JSONObject settings, Corpus corpus) {
        Filter filter = new Filter();
        // fixed values
        filter.setNgramValue(1);
        filter.setAl(AnalysisLevel.STRING_LEVEL);
        filter.setSkipValue(0);
        filter.setIsCvv(false);
        filter.setStringLength(1);

        // tab specific values
        // TODO
        ArrayList<String> prefixList = getArrayList((JSONArray) settings.get("prefixList"));
        filter.setPrefixList(prefixList);
        ArrayList<String> suffixList = getArrayList((JSONArray) settings.get("suffixList"));
        filter.setSuffixList(suffixList);

        String calculateForString = (String) settings.get("calculateFor");
        CalculateFor calculateFor = CalculateFor.factory(I18N.get(calculateForString));
        filter.setCalculateFor(calculateFor);
        ArrayList<String> alsoVisualize = getAlsoVisualizeList((JSONArray) settings.get("alsoVisualize"));
        filter.setMultipleKeys(alsoVisualize);
        filter.setDisplayTaxonomy((boolean) settings.get("displayTaxonomy"));
        filter.setMinimalRelFre(Math.toIntExact((Long) settings.get("minimalRelFre")));
        filter.setPrefixLength(Math.toIntExact((Long) settings.get("prefixLength")));
        filter.setSuffixLength(Math.toIntExact((Long) settings.get("suffixLength")));


        // right part
        ArrayList<Pattern> msd = getMsd((String) settings.get("msd"));
        filter.setMsd(msd);
        filter.setTaxonomySetOperation(I18N.get((String) settings.get("taxonomySetOperation")));
        ArrayList<Taxonomy> taxonomy = getTaxonomy((JSONArray) settings.get("taxonomy"), corpus);
        filter.setTaxonomy(taxonomy);
        filter.setMinimalOccurrences(Math.toIntExact((Long) settings.get("minimalOccurrences")));
        filter.setMinimalTaxonomy(Math.toIntExact((Long) settings.get("minimalTaxonomy")));

        String message = Validation.validateForStringLevel(filter);
        if (message == null) {
            // no errors
            logger.info("Executing: ", filter.toString());
            StatisticsNew statistic = new StatisticsNew(corpus, filter, false);
            execute(statistic, corpus);
            try {
                boolean successullySaved = statistic.saveResultToDisk();
                if (successullySaved) {
                    logger.info(I18N.get("message.NOTIFICATION_ANALYSIS_COMPLETED"));
                } else {
                    logger.info(I18N.get("message.NOTIFICATION_ANALYSIS_COMPLETED_NO_RESULTS"));
                }
            } catch (UnsupportedEncodingException e1) {
                logger.error(I18N.get("message.ERROR_WHILE_SAVING_RESULTS_TO_CSV"));
            }
        } else {
            logger.error(message);
        }
    }

    private static void execute(StatisticsNew statistic, Corpus corpus) {
        logger.info("Started execution: ", statistic.getFilter());

        if (statistic.getFilter().getMinimalRelFre() > 1){
            prepareTaskForMinRelFre(statistic, corpus);
        } else {
            prepareMainTask(statistic, corpus);
        }
    }
}
