"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const Project_1 = require("../app/Project");
const CartoApp_1 = require("../app/CartoApp");
const NodeStorage_1 = require("../local/NodeStorage");
const Database_1 = require("../minecraft/Database");
const LocalEnvironment_1 = require("../local/LocalEnvironment");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const child_process_1 = require("child_process");
const stringio_1 = require("@rauschma/stringio");
const fs = require("fs");
const Utilities_1 = require("../core/Utilities");
const ProjectInfoSet_1 = require("../info/ProjectInfoSet");
const IProjectInfoData_1 = require("../info/IProjectInfoData");
const ProjectUtilities_1 = require("../app/ProjectUtilities");
const axios_1 = require("axios");
CartoApp_1.default.hostType = CartoApp_1.HostType.testLocal;
let carto = undefined;
let localEnv = undefined;
let scenariosFolder = undefined;
let resultsFolder = undefined;
let sampleFolder = undefined;
localEnv = new LocalEnvironment_1.default(false);
(async () => {
    CartoApp_1.default.localFolderExists = _localFolderExists;
    CartoApp_1.default.ensureLocalFolder = _ensureLocalFolder;
    const testRootPath = NodeStorage_1.default.ensureEndsWithDelimiter(__dirname) + "/../../test/";
    const sampleContentRootPath = NodeStorage_1.default.ensureEndsWithDelimiter(__dirname) + "/../../../";
    const scenariosStorage = new NodeStorage_1.default(testRootPath, "scenarios");
    scenariosFolder = scenariosStorage.rootFolder;
    await scenariosFolder.ensureExists();
    const resultsStorage = new NodeStorage_1.default(testRootPath, "results");
    resultsFolder = resultsStorage.rootFolder;
    await resultsFolder.ensureExists();
    const sampleContentStorage = new NodeStorage_1.default(sampleContentRootPath, "samplecontent");
    sampleFolder = sampleContentStorage.rootFolder;
    await sampleFolder.ensureExists();
    CartoApp_1.default.prefsStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "prefs" + NodeStorage_1.default.platformFolderDelimiter, "");
    CartoApp_1.default.projectsStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "projects" + NodeStorage_1.default.platformFolderDelimiter, "");
    CartoApp_1.default.packStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "packs" + NodeStorage_1.default.platformFolderDelimiter, "");
    CartoApp_1.default.worldStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "worlds" + NodeStorage_1.default.platformFolderDelimiter, "");
    CartoApp_1.default.deploymentStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "deployment" + NodeStorage_1.default.platformFolderDelimiter, "");
    CartoApp_1.default.workingStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "working" + NodeStorage_1.default.platformFolderDelimiter, "");
    const coreStorage = new NodeStorage_1.default(__dirname + "/../../public/data/content/", "");
    Database_1.default.contentFolder = coreStorage.rootFolder;
    await CartoApp_1.default.init(); // carto app init does something here that, if removed, causes these tests to fail. Also, await needs to be here.
    carto = CartoApp_1.default.carto;
    if (!carto) {
        return;
    }
    await carto.load();
    run();
})();
function _ensureLocalFolder(path) {
    const ls = new NodeStorage_1.default(path, "");
    return ls.rootFolder;
}
async function _localFolderExists(path) {
    const ls = new NodeStorage_1.default(path, "");
    return await ls.rootFolder.exists();
}
function removeResultFolder(scenarioName) {
    if (resultsFolder) {
        const path = StorageUtilities_1.default.ensureEndsWithDelimiter(resultsFolder.fullPath) +
            StorageUtilities_1.default.ensureEndsWithDelimiter(scenarioName);
        // guard against being called at a "more root" file path
        if (fs.existsSync(path) && Utilities_1.default.countChar(path, NodeStorage_1.default.platformFolderDelimiter) > 5)
            try {
                fs.rmSync(path, {
                    recursive: true,
                });
            }
            catch (e) {
                console.log("Error occurred during rmSync on '" + path + "'");
                throw e;
            }
    }
}
function ensureResultFolder(scenarioName) {
    if (resultsFolder) {
        const path = StorageUtilities_1.default.ensureEndsWithDelimiter(resultsFolder.fullPath) +
            StorageUtilities_1.default.ensureEndsWithDelimiter(scenarioName);
        if (!fs.existsSync(path))
            // @ts-ignore
            fs.mkdirSync(path, {
                recursive: true,
            });
    }
}
describe("worldCommand", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    before(function (done) {
        this.timeout(10000);
        removeResultFolder("worldCommand");
        ensureResultFolder("worldCommand");
        const process = (0, child_process_1.spawn)("node", [
            " ./../toolbuild/jsn/cli",
            "world",
            "set",
            "-i",
            "./test/results/worldCommand",
            "-betaapis",
            "-o",
            "./test/results/worldCommand/",
        ]);
        collectLines(process.stdout, stdoutLines);
        collectLines(process.stderr, stderrLines);
        process.on("exit", (code) => {
            exitCode = code;
            done();
        });
    });
    it("should have no stderr lines", async () => {
        chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|");
    }).timeout(10000);
    it("exit code should be zero", async () => {
        chai_1.assert.equal(exitCode, 0);
    }).timeout(10000);
    it("output matches", async () => {
        await folderMatches("worldCommand");
    });
});
describe("serveCommandValidate", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    let process = null;
    before(function (done) {
        this.timeout(20000);
        removeResultFolder("serveCommandValidate");
        const passcode = Utilities_1.default.createUuid().substring(0, 8);
        if (!sampleFolder) {
            throw new Error("Sample folder does not exist.");
        }
        sampleFolder
            .ensureFileFromRelativePath("/addon/build/packages/aop_moremobs_animationmanifesterrors.zip")
            .then((sampleFile) => {
            console.log("Starting web server.");
            process = (0, child_process_1.spawn)("node", [
                " ./../toolbuild/jsn/cli",
                "serve",
                "basicwebservices",
                "-lv",
                "-once",
                "-updatepc",
                passcode,
            ]);
            collectLines(process.stdout, stdoutLines);
            collectLines(process.stderr, stderrLines);
            sampleFile.loadContent().then(() => {
                const content = sampleFile.content;
                Utilities_1.default.sleep(3000).then(() => {
                    console.log("Making validation web request to http://localhost:6126/api/validate/ " + content?.length + " bytes");
                    axios_1.default
                        .post("http://localhost:6126/api/validate/", content, {
                        headers: { mctpc: passcode, "content-type": "application/zip" },
                        method: "POST",
                    })
                        .then((response) => {
                        ensureJsonMatchesScenario(response.data, "serveCommandValidate");
                        if (response === undefined) {
                            throw new Error("Could not connect to server.");
                        }
                        if (process) {
                            process.on("exit", (code) => {
                                exitCode = code;
                                process = null;
                                done();
                            });
                        }
                    });
                });
            });
        });
    });
    it("should have no stderr lines", async () => {
        if (process) {
            process.kill();
            process = null;
        }
        chai_1.assert.equal(stderrLines.length, 0, "Error: " + stderrLines.join("\n") + "|");
    }).timeout(10000);
    it("exit code should be zero", async () => {
        if (process) {
            process.kill();
            process = null;
        }
        chai_1.assert.equal(exitCode, 0);
    }).timeout(10000);
    it("output matches", async () => {
        await folderMatches("serveCommandValidate");
    });
    after(function () {
        if (process) {
            console.log("Ending web process in after function.");
            process.kill();
            process = null;
        }
    });
});
describe("createCommandAddonStarter", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    let project = null;
    let allProjectInfoSet = null;
    let addonProjectInfoSet = null;
    before(function (done) {
        this.timeout(10000);
        removeResultFolder("createCommandAddonStarter");
        const process = (0, child_process_1.spawn)("node", [
            " ./../toolbuild/jsn/cli",
            "create",
            "testerName",
            "addonStarter",
            "testerCreatorName",
            "testerDescription",
            "-o",
            "./test/results/createCommandAddonStarter/",
        ]);
        collectLines(process.stdout, stdoutLines);
        collectLines(process.stderr, stderrLines);
        process.on("exit", (code) => {
            exitCode = code;
            (0, chai_1.assert)(carto, "Carto is not properly initialized");
            project = new Project_1.default(carto, "createCommandAddonStarter", null);
            // exclude eslint because we know the .ts comes with some warnings due to
            // the starter TS having some unused variables.
            allProjectInfoSet = new ProjectInfoSet_1.default(project, IProjectInfoData_1.ProjectInfoSuite.allExceptAddOn, ["ESLINT"]);
            addonProjectInfoSet = new ProjectInfoSet_1.default(project, IProjectInfoData_1.ProjectInfoSuite.addOn);
            project.autoDeploymentMode = Project_1.ProjectAutoDeploymentMode.noAutoDeployment;
            project.localFolderPath = __dirname + "/../../test/results/createCommandAddonStarter/";
            project.inferProjectItemsFromFiles().then(() => {
                (0, chai_1.assert)(project);
                ProjectUtilities_1.default.setIsAddon(project).then(() => {
                    (0, chai_1.assert)(allProjectInfoSet);
                    allProjectInfoSet.generateForProject().then(() => {
                        (0, chai_1.assert)(addonProjectInfoSet);
                        addonProjectInfoSet.generateForProject().then(() => {
                            done();
                        });
                    });
                });
            });
        });
    });
    it("should have no stderr lines", async () => {
        chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|");
    }).timeout(10000);
    it("exit code should be zero", async () => {
        chai_1.assert.equal(exitCode, 0);
    }).timeout(10000);
    it("should have 17 project items", async () => {
        (0, chai_1.assert)(project);
        chai_1.assert.equal(project.items.length, 17);
    }).timeout(10000);
    it("main validation should have 0 errors, failures, or warnings", async () => {
        (0, chai_1.assert)(allProjectInfoSet);
        chai_1.assert.equal(allProjectInfoSet.errorFailWarnCount, 0, allProjectInfoSet.errorFailWarnString);
    }).timeout(10000);
    it("addon validation should have 0 errors, failures, or warnings", async () => {
        (0, chai_1.assert)(addonProjectInfoSet);
        chai_1.assert.equal(addonProjectInfoSet.errorFailWarnCount, 0, addonProjectInfoSet.errorFailWarnString);
    }).timeout(10000);
    it("output matches", async () => {
        await folderMatches("createCommandAddonStarter", ["manifest.json"]);
    });
});
describe("validateAddons1WellFormedCommand", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    before(function (done) {
        this.timeout(10000);
        removeResultFolder("validateAddons1WellFormedCommand");
        const process = (0, child_process_1.spawn)("node", [
            " ./../toolbuild/jsn/cli",
            "val",
            "addon",
            "-i",
            "./../samplecontent/addon/build/content1",
            "-o",
            "./test/results/validateAddons1WellFormedCommand/",
        ]);
        collectLines(process.stdout, stdoutLines);
        collectLines(process.stderr, stderrLines);
        process.on("exit", (code) => {
            exitCode = code;
            done();
        });
    });
    it("should have no stderr lines", function (done) {
        chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|");
        done();
    }).timeout(10000);
    it("exit code should be zero", function (done) {
        chai_1.assert.equal(exitCode, 0);
        done();
    }).timeout(10000);
    it("output matches", async function () {
        await folderMatches("validateAddons1WellFormedCommand");
    }).timeout(10000);
});
describe("validateAddons2AnimationManifestErrorsCommand", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    before(function (done) {
        this.timeout(10000);
        removeResultFolder("validateAddons2AnimationManifestErrorsCommand");
        const process = (0, child_process_1.spawn)("node", [
            " ./../toolbuild/jsn/cli",
            "val",
            "addon",
            "-i",
            "./../samplecontent/addon/build/content2",
            "-o",
            "./test/results/validateAddons2AnimationManifestErrorsCommand/",
        ]);
        collectLines(process.stdout, stdoutLines);
        collectLines(process.stderr, stderrLines);
        process.on("exit", (code) => {
            exitCode = code;
            done();
        });
    });
    it("should have no stderr lines", async (done) => {
        chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|");
        done();
    }).timeout(10000);
    it("exit code should be zero", async (done) => {
        chai_1.assert.equal(exitCode, 0);
        done();
    }).timeout(10000);
    it("output matches", async function () {
        await folderMatches("validateAddons2AnimationManifestErrorsCommand");
    }).timeout(10000);
});
describe("validateAddons3ExtraneousStuffUsesMinecraftCommand", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    before(function (done) {
        this.timeout(20000);
        removeResultFolder("validateAddons3ExtraneousStuffUsesMinecraftCommand");
        const process = (0, child_process_1.spawn)("node", [
            " ./../toolbuild/jsn/cli",
            "val",
            "addon",
            "-i",
            "./../samplecontent/addon/build/content3",
            "-o",
            "./test/results/validateAddons3ExtraneousStuffUsesMinecraftCommand/",
        ]);
        collectLines(process.stdout, stdoutLines);
        collectLines(process.stderr, stderrLines);
        process.on("exit", (code) => {
            exitCode = code;
            done();
        });
    });
    it("should have no stderr lines", async (done) => {
        chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|");
        done();
    }).timeout(10000);
    it("exit code should be zero", async (done) => {
        chai_1.assert.equal(exitCode, 0);
        done();
    }).timeout(10000);
    it("output matches", async function () {
        await folderMatches("validateAddons3ExtraneousStuffUsesMinecraftCommand");
    });
});
describe("validateAddons3PlatformVersions", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    before(function (done) {
        this.timeout(20000);
        removeResultFolder("validateAddons3PlatformVersions");
        const process = (0, child_process_1.spawn)("node", [
            " ./../toolbuild/jsn/cli",
            "val",
            "currentplatform",
            "-i",
            "./../samplecontent/addon/build/content3",
            "-o",
            "./test/results/validateAddons3PlatformVersions/",
        ]);
        collectLines(process.stdout, stdoutLines);
        collectLines(process.stderr, stderrLines);
        process.on("exit", (code) => {
            exitCode = code;
            done();
        });
    });
    it("should have no stderr lines", async (done) => {
        chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|");
        done();
    }).timeout(10000);
    it("exit code should be zero", async (done) => {
        chai_1.assert.equal(exitCode, 0);
        done();
    }).timeout(10000);
    it("output matches", async function () {
        await folderMatches("validateAddons3PlatformVersions");
    });
});
describe("validateLinkErrors", async () => {
    let exitCode = null;
    const stdoutLines = [];
    const stderrLines = [];
    before(function (done) {
        this.timeout(20000);
        removeResultFolder("validateLinkErrors");
        const process = (0, child_process_1.spawn)("node", [
            " ./../toolbuild/jsn/cli",
            "val",
            "all",
            "-i",
            "./../samplecontent/addon/build/content_linkerrors",
            "-o",
            "./test/results/validateLinkErrors/",
        ]);
        collectLines(process.stdout, stdoutLines);
        collectLines(process.stderr, stderrLines);
        process.on("exit", (code) => {
            exitCode = code;
            done();
        });
    });
    it("should have no stderr lines", async (done) => {
        chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|");
        done();
    }).timeout(10000);
    it("exit code should be zero", async (done) => {
        chai_1.assert.equal(exitCode, 0);
        done();
    }).timeout(10000);
    it("output matches", async function () {
        await folderMatches("validateLinkErrors");
    });
});
async function collectLines(readable, data) {
    for await (const line of (0, stringio_1.chunksToLinesAsync)(readable)) {
        if (line !== undefined && line.length >= 0) {
            let lineUp = line.replace(/\\n/g, "");
            lineUp = lineUp.replace(/\\r/g, "");
            // ignore any lines about the debugger.
            if (lineUp.indexOf("ebugger") <= 0) {
                //console.log(lineUp);
                data.push(lineUp);
            }
        }
    }
}
async function folderMatches(scenarioName, excludeFileList) {
    if (!scenariosFolder || !resultsFolder) {
        chai_1.assert.fail("Not properly initialized");
    }
    const scenarioOutFolder = resultsFolder.ensureFolder(scenarioName);
    await scenarioOutFolder.ensureExists();
    const scenarioFolder = scenariosFolder.ensureFolder(scenarioName);
    const isEqual = await StorageUtilities_1.default.folderContentsEqual(scenarioFolder, scenarioOutFolder, excludeFileList, true, [
        "generatorVersion",
        "uuid",
        "version",
    ]);
    (0, chai_1.assert)(isEqual.result, "Folder '" + scenarioFolder.fullPath + "' does not match for scenario '" + scenarioName + "', " + isEqual.reason);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async function ensureJsonMatchesScenario(obj, scenarioName) {
    if (!scenariosFolder || !resultsFolder) {
        chai_1.assert.fail("Not properly initialized");
    }
    const dataObjectStr = JSON.stringify(obj, null, 2);
    const scenarioOutFolder = resultsFolder.ensureFolder(scenarioName);
    await scenarioOutFolder.ensureExists();
    const outFile = scenarioOutFolder.ensureFile("report.json");
    outFile.setContent(dataObjectStr);
    await outFile.saveContent();
    const scenarioFile = scenariosFolder.ensureFolder(scenarioName).ensureFile("report.json");
    const exists = await scenarioFile.exists();
    (0, chai_1.assert)(exists, "report.json file for scenario '" + scenarioName + "' does not exist.");
    const isEqual = await StorageUtilities_1.default.fileContentsEqual(scenarioFile, outFile, true, [
        "generatorVersion",
        "uuid",
        "version",
    ]);
    (0, chai_1.assert)(isEqual, "report.json file '" + scenarioFile.fullPath + "' does not match for scenario '" + scenarioName + "'");
}

//# sourceMappingURL=../maps/test/CommandLineTest.js.map
