
const fs = require("fs");
const nlp = require("../js/nlpServices");
const { getRootPath, setRootPath } = require("../rootPath")
const TextAnalysisManager = require('../js/textAnalysisManager');
const TextAnalysisManagerDev = require('../js/textAnalysisManagerDev');

const dictionaryServices = require("./dictionaryServices");
const corpusServices = require("./corpusServices");
const splitLine = require('./splitCSVLine');
const fullNLP = true;

const directNLP = require("../wordServices/nlp");

let checkPerformance = false;

var sentences = [];

var config = {
    env: "development", // production
    // buildRules: false,
    updateRuleLists: false,
    allTestInput: false,
    testInputFile: "",
    lessonRules: false,
    errorRules: false,
    category: "",
    ruleId: "",
    // compareWithReferences: false,
    generateDictionaries: false,
    language: "en",
    conflictMode: 0
};

function computeConfig() {
    var args = process.argv;
    for (var i = 0; i < args.length; i++) {
        if (args[i] == "--production") {
            config.env = "production";
        }
        else if (args[i] == "--buildRules") {
            debugger;
            console.error("buildRules is no more working");
            return;
            //config.buildRules = true;
        }
        else if (args[i] == "--generateDictionaries") {
            config.generateDictionaries = true;
        }
        else if (args[i] == "--updateRuleLists") {
            config.updateRuleLists = true;
        }
        else if (args[i] == "--allTestInput") {
            config.allTestInput = true;
        }
        else if (args[i] == "--testInputFile") {
            if (i + 1 < args.length) {
                i++;
                config.testInputFile = args[i];
            }
        }
        else if (args[i] == "--language") {
            if (i + 1 < args.length) {
                i++;
                config.language = args[i];
            }
        }
        else if (args[i] == "--lessonRules") {
            config.lessonRules = true;
        }
        else if (args[i] == "--errorRules") {
            config.errorRules = true;
        }
        // else if (args[i]=="--compareWithReferences")
        // {
        //     config.compareWithReferences = true;
        // }
        else if (args[i] == "--category") {
            if (i + 1 < args.length) {
                i++;
                config.category = args[i];
            }
        }
        else if (args[i] == "--ruleId") {
            if (i + 1 < args.length) {
                i++;
                config.ruleId = args[i];
            }
        }
        // else if (args[i]=="--prefixLocalRootFolder")
        // {
        //     if (i+1<args.length)
        //     {
        //         i++;
        //         config.prefixLocalRootFolder = args[i];
        //     }
        // }
    }
}
function GetSentencesFromTextFile(folder, file) {
    var lines = fs.readFileSync(folder + file).toString().split(/(?:\r\n?|\n)/);
    for (var wi = 0; wi < lines.length; wi++) {
        var sentence = lines[wi];
        if (sentence != "" && !sentence.startsWith("//")) {
            sentences.push(sentence);
        }
    }
}
function ReadCSVFile(folder, file) {
    var lines = fs.readFileSync(folder + file).toString().split(/(?:\r\n?|\n)/);
    if (lines.length) {
        var indice = -1;
        var data = splitLine(lines[0]);
        for (var di = 0; di < data.length; di++) {
            if (data[di] == "sentence") {
                indice = di;
                break;
            }
        }
        if (indice != -1) {
            for (var wi = 1; wi < lines.length; wi++) {
                var line = lines[wi];
                if (line != "" && !line.startsWith("//")) {
                    var data = splitLine(line);
                    if (data.length > indice) {
                        var sentence = data[indice];
                        sentences.push(sentence);
                    }
                }
            }
        }
    }
}
function GetSentences(folder, file) {
    if (file.length > 4) {
        if (file.endsWith(".txt")) {
            GetSentencesFromTextFile(folder, file);
        }
        else if (file.endsWith(".csv")) {
            ReadCSVFile(folder, file);
        }
        else {
            debugger;
        }
    }
}
// function GetErrorSentences(folder, file)
// {
//     if (file.length > 4) {
//         if (file.endsWith(".txt")) {
//             GetSentencesFromTextFile(folder, file);
//         }
//         else if (file.endsWith(".csv"))
//         {
//             ReadCSVFile(folder, file);
//         }
//         else{
//             debugger;
//         }
//     }
// }



function IdentifyLearningCards(srm, language, indice, sentences, checkErrors, options) {
    if (indice == 0) {
        console.log("LEARNINGCARD IDENTIFICATION STARTED");
    }
    if (indice >= sentences.length) {
        if (config.env == "development") {
            if (config.conflictMode == 0) {
                srm.StreamConflictRules();
            }
            else if (config.errorRules && config.lessonRules) {
                srm.StreamConflictRules();
            }
        }
        console.log("LEARNINGCARD IDENTIFICATION ENDED");
        return;
    }
    var sentence = sentences[indice];

    nlp.GetTextNLP(language, sentence, null, false, fullNLP)
        .then(function (nlpResult) {

            for (var i = 0; i < nlpResult.sentences.length; i++) {
                var nlpSentence = nlpResult.sentences[i];
                var lessonResults = [];
                var errorResults = [];
                var localSentence = nlp.GetTextNLPAsString2({ sentences: [nlpSentence] });
                console.log("NEW ANALYSIS: " + localSentence);
                if (checkErrors) {
                    options.sentence = localSentence;
                    srm.Analyze(nlpSentence, lessonResults, errorResults, options);
                }
                else {
                    srm.IdentifyLearningCards(nlpSentence, lessonResults, {});
                }
                srm.LogResult(nlpSentence, lessonResults);

                if (checkErrors) {
                    OnCheckErrorsDone(srm, sentences[indice], nlpSentence, errorResults);
                }
                console.log("");
            }
            IdentifyLearningCards(srm, language, indice + 1, sentences, checkErrors, options);
        }).catch(function (error) {
            console.error(error.message);
            debugger;
        });
}
function OnCheckErrorsDone(srm, originalText, nlpSentence, results) {
    srm.LogResult(nlpSentence, results);

    var modifTokenServices = corpusServices.GetModificationTokenServices("errors", nlpSentence, results);
    var json = modifTokenServices.GetAllCorrectionSuggestions(originalText);

    for (ci = 0; ci < json.corrections.length; ci++) {
        var correction = json.corrections[ci];
        console.log("Suggestion: " + ci + " - " + originalText + " -> " + correction.sentence);
    }
    // if (config.compareWithReferences)
    // {
    //     var folder = refenrencesFolder + "errorDetections/";
    //     srm.CompareWithReferences(folder, sentence, localResults);
    // }
}
function CheckErrors(srm, language, indice, sentences) {
    if (indice == 0) {
        console.log("ERROR DETECTION STARTED");
    }
    if (indice >= sentences.length) {
        console.log("ERROR DETECTION ENDED");
        srm.StreamConflictRules();
        return;
    }
    var sentence = sentences[indice];
    nlp.GetTextNLP(language, sentence).then(nlpResult => {
        // console.log("Start CheckErrors with sentence= "+sentence);
        for (var i = 0; i < nlpResult.sentences.length; i++) {
            var nlpSentence = nlpResult.sentences[i];
            var results = [];
            srm.CheckErrors(nlpSentence, results, {});
            OnCheckErrorsDone(srm, sentence, nlpSentence, results);
        }
        CheckErrors(srm, language, indice + 1, sentences);
    }).catch(function (error) {
        console.log(error.message);
        debugger;
    });
}
function CheckPerformance(output, language, indice, sentences) {
    if (indice >= sentences.length) {
        console.log("ERROR DETECTION ENDED");
        return;
    }
    var sentence = sentences[indice];
    let start = new Date().getTime();
    directNLP.GetTextNLP(language, sentence).then(nlpResult => {
        // console.log("Start CheckErrors with sentence= "+sentence);
        let end = new Date().getTime();
        let log = '"' + sentence + '",' + (end - start);
        start = new Date().getTime();
        directNLP.GetTextNLP(language, sentence, true).then(nlpResult => {
            // console.log("Start CheckErrors with sentence= "+sentence);
            end = new Date().getTime();
            log += "," + (end - start);
            console.log(log);
            fs.appendFileSync(output, log + "\n");
            CheckPerformance(output, language, indice + 1, sentences);
        }).catch(function (error) {
            console.log(error.message);
            debugger;
        });
    }).catch(function (error) {
        console.log(error.message);
        debugger;
    });

}
function StartTest(inRootPath) {
    computeConfig()

    if (inRootPath) {
        setRootPath(inRootPath)
    }
    const localRootPath = getRootPath()

    if (config.allTestInput) {
        // -------------------------
        // test with all input files
        // -------------------------

        var folder = "./" + localRootPath + config.language + "/tests/inputs/errors/";
        fs.readdirSync(folder).forEach(file => {
            if (file.length > 4 && file.endsWith(".csv")) {
                //GetErrorSentences(folder, file);
                ReadCSVFile(folder, file);
            }
        });
        var folder = "./" + localRootPath + config.language + "/tests/inputs/lessons/";
        fs.readdirSync(folder).forEach(file => {
            if (file.length > 4 && file.endsWith(".txt")) {
                GetSentences(folder, file);
            }
        });
    }
    else if (config.testInputFile != "") {
        // ---------------------------------
        // test with all specific input file
        // ---------------------------------
        var folder = "./" + localRootPath + config.language + "/tests/inputs/";
        var file = config.testInputFile;
        GetSentences(folder, file);
    }
    else {
        var folder = "./" + localRootPath + config.language + "/misc/";
        var file = "sentences.txt";
        GetSentences(folder, file);
    }




    var srm = null;
    if (config.updateRuleLists) {
        console.log("UpdateRuleLists started");
        TextAnalysisManager.UpdateRuleLists(null, config.language);
        console.log("UpdateRuleLists ended");
        return;
    }
    if (checkPerformance) {
        console.log("checkPerformance started");
        let output = "output.csv";
        if (fs.existsSync(output)) {
            fs.unlinkSync(output);
        }
        CheckPerformance(output, config.language, 0, sentences);
        return;
    }
    // Build
    // if (config.buildRules)
    // {
    //     TextAnalysisManager.BuildRules(config.language);
    // }
    // Build
    if (config.generateDictionaries) {
        console.log("GenerateDictionaries started");
        dictionaryServices.GenerateDictionaries();
        console.log("GenerateDictionaries ended");
        return;
    }
    var ruleTypes = "";
    if (config.lessonRules) {
        if (config.errorRules) {
            ruleTypes = "allRules";
        }
        else {
            ruleTypes = "lessonRules";
        }
    }
    else if (config.errorRules) {
        ruleTypes = "errorRules";
    }
    else {
        console.error("rule type is not defined (lessonRules or errorRules)");
        return;
    }
    let amOptions = {
        prefixFolders: {
            root: "./" + localRootPath,
            local: "../"
        },
        conflictMode: config.conflictMode
    };
    //
    // development mode
    //
    if (config.env == "development") {
        // instanciate srm in development mode
        srm = new TextAnalysisManagerDev(amOptions, config.language, ruleTypes, config.category, config.ruleId);

    }
    //
    // production mode
    //
    else if (config.env == "production") {
        srm = new TextAnalysisManager(amOptions, config.language, ruleTypes, config.category, config.ruleId);
    }
    else {
        console.error("env is wrong env= " + config.env);
        return;
    }
    if (config.lessonRules) {
        if (srm) {
            if (config.errorRules) {
                var fileName = "./" + localRootPath + config.language + "/removedResults.csv";
                if (fs.existsSync(fileName)) {
                    fs.unlinkSync(fileName);
                }
                var options = {
                    generateConflictRules: true,
                    toRemoveResultsFileName: fileName
                };
                // with error checking
                IdentifyLearningCards(srm, config.language, 0, sentences, 1, options);
            }
            else {
                var options = {}
                // without error checking
                IdentifyLearningCards(srm, config.language, 0, sentences, 0, options);
            }
        }
        else {
            console.error("srm is not defined");
        }
    }
    else if (config.errorRules) {
        if (srm) {
            CheckErrors(srm, config.language, 0, sentences);
        }
        else {
            console.error("srm is not defined");
        }
    }
}

module.exports = { startAnalysis: StartTest };