// This package needs to be install:
//
// ```
// npm install browser-ui-test
// ```

const fs = require("fs");
const path = require("path");
const os = require("os");
const {Options, runTest} = require("browser-ui-test");

// If a test fails or errors, we will retry it two more times in case it was a flaky failure.
const NB_RETRY = 3;

function showHelp() {
    console.log("rustdoc-js options:");
    console.log("  --doc-folder [PATH]        : location of the generated doc folder");
    console.log("  --file [PATH]              : file to run (can be repeated)");
    console.log("  --debug                    : show extra information about script run");
    console.log("  --show-text                : render font in pages");
    console.log("  --no-headless              : disable headless mode");
    console.log("  --help                     : show this message then quit");
    console.log("  --tests-folder [PATH]      : location of the .GOML tests folder");
    console.log("  --jobs [NUMBER]            : number of threads to run tests on");
    console.log("  --executable-path [PATH]   : path of the browser's executable to be used");
}

function isNumeric(s) {
    return /^\d+$/.test(s);
}

function parseOptions(args) {
    const opts = {
        "doc_folder": "",
        "tests_folder": "",
        "files": [],
        "debug": false,
        "show_text": false,
        "no_headless": false,
        "jobs": -1,
        "executable_path": null,
    };
    const correspondences = {
        "--doc-folder": "doc_folder",
        "--tests-folder": "tests_folder",
        "--debug": "debug",
        "--show-text": "show_text",
        "--no-headless": "no_headless",
        "--executable-path": "executable_path",
    };

    for (let i = 0; i < args.length; ++i) {
        const arg = args[i];
        if (arg === "--doc-folder"
            || arg === "--tests-folder"
            || arg === "--file"
            || arg === "--jobs"
            || arg === "--executable-path") {
            i += 1;
            if (i >= args.length) {
                console.log("Missing argument after `" + arg + "` option.");
                return null;
            }
            const arg_value = args[i];
            if (arg === "--jobs") {
                if (!isNumeric(arg_value)) {
                    console.log(
                        "`--jobs` option expects a positive number, found `" + arg_value + "`");
                    return null;
                }
                opts["jobs"] = parseInt(arg_value);
            } else if (arg !== "--file") {
                opts[correspondences[arg]] = arg_value;
            } else {
                opts["files"].push(arg_value);
            }
        } else if (arg === "--help") {
            showHelp();
            process.exit(0);
        } else if (correspondences[arg]) {
            opts[correspondences[arg]] = true;
        } else {
            console.log("Unknown option `" + arg + "`.");
            console.log("Use `--help` to see the list of options");
            return null;
        }
    }
    if (opts["tests_folder"].length < 1) {
        console.log("Missing `--tests-folder` option.");
    } else if (opts["doc_folder"].length < 1) {
        console.log("Missing `--doc-folder` option.");
    } else {
        return opts;
    }
    return null;
}

/// Print single char status information without \n
function char_printer(n_tests) {
    const max_per_line = 10;
    let current = 0;
    return {
        successful: function() {
            current += 1;
            if (current % max_per_line === 0) {
                process.stdout.write(`. (${current}/${n_tests})${os.EOL}`);
            } else {
                process.stdout.write(".");
            }
        },
        erroneous: function() {
            current += 1;
            if (current % max_per_line === 0) {
                process.stderr.write(`F (${current}/${n_tests})${os.EOL}`);
            } else {
                process.stderr.write("F");
            }
        },
        finish: function() {
            if (current % max_per_line === 0) {
                // Don't output if we are already at a matching line end
                console.log("");
            } else {
                const spaces = " ".repeat(max_per_line - (current % max_per_line));
                process.stdout.write(`${spaces} (${current}/${n_tests})${os.EOL}${os.EOL}`);
            }
        },
    };
}

// Sort array by .file_name property
function by_filename(a, b) {
    return a.file_name - b.file_name;
}

async function runTests(opts, framework_options, files, results, status_bar, showTestFailures) {
    const tests_queue = [];

    for (const testPath of files) {
        const callback = runTest(testPath, {"options": framework_options})
            .then(out => {
                const [output, nb_failures] = out;
                results[nb_failures === 0 ? "successful" : "failed"].push({
                    file_name: testPath,
                    output: output,
                });
                if (nb_failures === 0) {
                    status_bar.successful();
                } else if (showTestFailures) {
                    status_bar.erroneous();
                }
            })
            .catch(err => {
                results.errored.push({
                    file_name: testPath,
                    output: err,
                });
                if (showTestFailures) {
                    status_bar.erroneous();
                }
            })
            .finally(() => {
                // We now remove the promise from the tests_queue.
                tests_queue.splice(tests_queue.indexOf(callback), 1);
            });
        tests_queue.push(callback);
        if (opts["jobs"] > 0 && tests_queue.length >= opts["jobs"]) {
            await Promise.race(tests_queue);
        }
    }
    if (tests_queue.length > 0) {
        await Promise.all(tests_queue);
    }
}

function createEmptyResults() {
    return {
        successful: [],
        failed: [],
        errored: [],
    };
}

async function main(argv) {
    const opts = parseOptions(argv.slice(2));
    if (opts === null) {
        process.exit(1);
    }

    // Print successful tests too
    let debug = false;
    // Run tests in sequentially
    let headless = true;
    const framework_options = new Options();
    try {
        // This is more convenient that setting fields one by one.
        const args = [
            "--variable", "DOC_PATH", opts["doc_folder"].split("\\").join("/"),
            "--enable-fail-on-js-error", "--allow-file-access-from-files",
            "--no-sandbox",
        ];
        if (opts["debug"]) {
            debug = true;
            args.push("--debug");
        }
        if (opts["show_text"]) {
            args.push("--show-text");
        }
        if (opts["no_headless"]) {
            args.push("--no-headless");
            headless = false;
        }
        if (opts["executable_path"] !== null) {
            args.push("--executable-path");
            args.push(opts["executable_path"]);
        }
        framework_options.parseArguments(args);
    } catch (error) {
        console.error(`invalid argument: ${error}`);
        process.exit(1);
    }

    let files;
    if (opts["files"].length === 0) {
        files = fs.readdirSync(opts["tests_folder"]);
    } else {
        files = opts["files"];
    }
    files = files.filter(file => path.extname(file) === ".goml");
    if (files.length === 0) {
        console.error("rustdoc-gui: No test selected");
        process.exit(2);
    }
    files.forEach((file_name, index) => {
        files[index] = path.join(opts["tests_folder"], file_name);
    });
    files.sort();

    if (!headless) {
        opts["jobs"] = 1;
        console.log("`--no-headless` option is active, disabling concurrency for running tests.");
    }

    if (opts["jobs"] < 1) {
        const len = files.length;
        console.log(
            `Running ${len} rustdoc-gui (UNBOUNDED concurrency; use "-j#" for a limit) ...`,
        );
        process.setMaxListeners(files.length + 1);
    } else if (headless) {
        console.log(`Running ${files.length} rustdoc-gui (${opts["jobs"]} concurrently) ...`);
        process.setMaxListeners(opts["jobs"] + 1);
    } else {
        console.log(`Running ${files.length} rustdoc-gui ...`);
    }

    const originalFilesLen = files.length;
    const results = createEmptyResults();
    const status_bar = char_printer(files.length);

    let new_results;
    for (let it = 0; it < NB_RETRY && files.length > 0; ++it) {
        new_results = createEmptyResults();
        await runTests(opts, framework_options, files, new_results, status_bar, it + 1 >= NB_RETRY);
        Array.prototype.push.apply(results.successful, new_results.successful);
        // We generate the new list of files with the previously failing tests.
        files = Array.prototype.concat(new_results.failed, new_results.errored).map(
            f => f["file_name"]);
        if (files.length > originalFilesLen / 2) {
            // If we have too many failing tests, it's very likely not flaky failures anymore so
            // no need to retry.
            break;
        }
    }

    status_bar.finish();

    Array.prototype.push.apply(results.failed, new_results.failed);
    Array.prototype.push.apply(results.errored, new_results.errored);

    if (debug) {
        results.successful.sort(by_filename);
        results.successful.forEach(r => {
            console.log(r.output);
        });
    }

    if (results.failed.length > 0) {
        console.log("");
        results.failed.sort(by_filename);
        results.failed.forEach(r => {
            console.log(r.file_name, r.output);
        });
    }
    if (results.errored.length > 0) {
        console.log(os.EOL);
        // print run errors on the bottom so developers see them better
        results.errored.sort(by_filename);
        results.errored.forEach(r => {
            console.error(r.file_name, r.output);
        });
    }

    if (results.failed.length > 0 || results.errored.length > 0) {
        process.exit(1);
    }
    process.exit(0);
}

main(process.argv);
