package nogui;

import data.*;
import gui.GUIController;
import gui.I18N;
import gui.ValidationUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;


import java.io.*;
import java.util.*;

import static data.CorpusType.*;
import static data.CorpusType.GIGAFIDA;
import static nogui.Characters.characters;
import static nogui.WordSets.wordSets;
import static nogui.Words.words;
import static nogui.WordParts.wordParts;

public class NoGUIController {

    public final static Logger logger = LogManager.getLogger(GUIController.class);

    public static void launch_no_gui(String [] args) {
        Filter filter = new Filter();

        String path = null;
        String corpusLocation = null;
        String outputName = null;
        String resultsLocation = null;
        // read parameters
        int i = 0;
        for(String s : args) {
            switch (s) {
                case "--config":  // we check for if it is equal to -v
                    path = args[i + 1];
                    break;
                case "--corpusLocation":  // in an else if to have no input = -v
                    corpusLocation = args[i + 1];
                    break;
                case "--outputName":  // in an else if to have no input = -v
                    outputName = args[i + 1];
                    break;
                case "--resultsLocation":  // in an else if to have no input = -v
                    resultsLocation = args[i + 1];
                    break;
            }
            i ++;
        }

        // read config file
        JSONObject settings = read_config(path);

        // read corpus
        Corpus corpus = read_corpus(settings, corpusLocation, outputName, resultsLocation);

        if (((String) settings.get("language")).equals("SL")) {
            I18N.setLocale(new Locale.Builder().setLanguage("sl").setRegion("SI").build());
        } else {
            I18N.setLocale(Locale.ENGLISH);
        }

        // handle chars
        if (((String) settings.get("tab")).equals("characters")) {
            characters(settings, corpus);
        } else if (((String) settings.get("tab")).equals("wordParts")) {
            wordParts(settings, corpus);
        } else if (((String) settings.get("tab")).equals("words")) {
            words(settings, corpus);
        } else if (((String) settings.get("tab")).equals("wordSets")) {
            wordSets(settings, corpus);
        }
    }


    private static Corpus read_corpus(JSONObject settings, String corpusLocationS, String outputNameS, String resultsLocationS) {
        Corpus corpus = new Corpus();

        if (corpusLocationS == null) {
            corpusLocationS = (String) settings.get("corpusLocation");
        }

        File corpusLocation = new File(corpusLocationS);
        corpus.setChosenCorpusLocation(corpusLocation);

        boolean readHeaderInfo = (Boolean) settings.get("readHeaderInfo");
        corpus.setHeaderRead(readHeaderInfo);

        if (resultsLocationS == null) {
            resultsLocationS = (String) settings.get("resultsLocation");
        }

        File resultsLocation = new File(resultsLocationS);
        corpus.setChosenResultsLocation(resultsLocation);

        CorpusType corpusType = selectReader((String) settings.get("selectReader"));
        corpus.setCorpusType(corpusType);

        if (outputNameS == null) {
            outputNameS = (String) settings.get("outputName");
        }
        corpus.setCorpusName(outputNameS);

        String punctuation = ((String) settings.get("punctuation")).equals("comma") ? "punctuation.COMMA" : "punctuation.POINT";
        corpus.setPunctuation(punctuation);

        Collection<File> corpusFiles = null;

        if (ValidationUtil.isReadableDirectory(corpusLocation)) {
            logger.info("selected corpus dir: ", corpusLocation.getAbsolutePath());

            // scan for xml files
            corpusFiles = FileUtils.listFiles(corpusLocation, FileFilterUtils.suffixFileFilter("xml", IOCase.INSENSITIVE), TrueFileFilter.INSTANCE);
        } else {
            corpusFiles = new LinkedList();
            corpusFiles.add(corpusLocation);
        }

        corpus.setDetectedCorpusFiles(corpusFiles);

        corpus.validate();

        // MISSING: setSolarFiltersForXML

        return corpus;
    }

    private static CorpusType selectReader(String selectReader) {
        CorpusType corpusType = null;
        switch (selectReader) {
//			"vert", "Solar", "GOS", "SSJ500K", "Gigafida", "Gigafida (old)", "Kres (old)"
            case "VERT + REGI":
                corpusType = VERT;
                break;
            case "XML (Šolar 1.0)":
                corpusType = SOLAR;
                break;
            case "XML (GOS 1.0)":
                corpusType = GOS;
                break;
            case "XML (ssj500k 2.1)":
                corpusType = SSJ500K;
                break;
            case "XML (Gigafida 2.0)":
                corpusType = GIGAFIDA2;
                break;
            case "XML (Gigafida 1.0, Kres 1.0)":
                corpusType = GIGAFIDA;
                break;
            default:
                break;
        }
        return corpusType;
    }

    private static JSONObject read_config(String path) {
        JSONObject settings = null;

        //JSON parser object to parse read file
        JSONParser jsonParser = new JSONParser();

        try (FileReader reader = new FileReader(path))
        {
            //Read JSON file
            Object obj = jsonParser.parse(reader);

            settings = (JSONObject) obj;
//            String selectReader = (String) settings.get("selectReader");
//            boolean readHeaderInfo = (Boolean) settings.get("readHeaderInfo");
//            employeeList.forEach( emp -> parseEmployeeObject( (JSONObject) emp ) );

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return settings;
//        chooseCorpusLocationL - selectedDirectory_input;
//        readHeaderInfo;
//        chooseResultsLocationL - selectedDirectory_output;
//        selectReader;
//        outputName;
//        punctuation;
//
//
//        Collection<File> corpusFiles = FileUtils.listFiles(selectedDirectory, FileFilterUtils.suffixFileFilter("xml", IOCase.INSENSITIVE), TrueFileFilter.INSTANCE);


    }
}
