#!/usr/bin/env node
"use strict";
/*
 * Copyright 2018, collaboration Factory AG. All rights reserved.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./model/utils");
const AssetsCompiler_1 = require("./model/AssetsCompiler");
const utils_2 = require("./utils");
const os = require("os");
const path = require("path");
const PackageVersion_1 = require("./model/PackageVersion");
const CplaceVersion_1 = require("./model/CplaceVersion");
const NodeUtils_1 = require("./utils/NodeUtils");
const fs = require("fs");
const meow = require("meow");
utils_2.checkForUpdate()
    .then((details) => run(details))
    .catch(() => run());
function run(updateDetails) {
    const cli = meow(`
    Usage:
        Go to the root folder of your cplace project. Then you can start cplace-asc: 
        $ cplace-asc

    Options:
        --plugin, -p <plugins>  Run for specified plugins (and dependencies) - comma separated list of plugin names
        --watch, -w             Enable watching of source files (continuous compilation)
        --onlypre, -o           Run only preprocessing steps (like create tsconfig.json files)
        --clean, -c             Clean generated output folders at the beginning
        --threads, -t           Maximum number of threads to run in parallel
        --localonly, -l         Enable to not scan other directories than CWD for plugins
        --noparents, -x         Enable to only run compilation on plugins in current repository (still scans for other sources to be present)
        --packagejson, -j       Generate package.json files (if missing) in the root and each plugin that has assets
        --withYaml, -y          Generates TypeScript files from the OpenAPI YAML specification
        --verbose, -v           Enable verbose logging
        --production, -P        Enable production mode (ignores test dependencies and E2E)
        --cplaceversion, -V     Explicitly specify the current cplace version

`, {
        flags: {
            plugin: {
                type: 'string',
                alias: 'p',
                default: null,
            },
            watch: {
                type: 'boolean',
                alias: 'w',
                default: false,
            },
            onlypre: {
                type: 'boolean',
                alias: 'o',
                default: false,
            },
            clean: {
                type: 'boolean',
                alias: 'c',
                default: false,
            },
            withYaml: {
                type: 'boolean',
                alias: 'y',
                default: false,
            },
            threads: {
                type: 'string',
                alias: 't',
                default: null,
            },
            localonly: {
                type: 'boolean',
                alias: 'l',
                default: false,
            },
            noparents: {
                type: 'boolean',
                alias: 'x',
                default: false,
            },
            packagejson: {
                type: 'boolean',
                alias: 'j',
                default: false,
            },
            verbose: {
                type: 'boolean',
                alias: 'v',
                default: false,
            },
            production: {
                type: 'boolean',
                alias: 'P',
                default: false,
            },
            cplaceversion: {
                type: 'string',
                alias: 'V',
                default: '',
            },
        },
    });
    CplaceVersion_1.CplaceVersion.initialize(process.cwd(), cli.flags.cplaceversion);
    checkNodeVersion();
    if (cli.flags.plugin !== null && !cli.flags.plugin) {
        console.error(utils_2.cerr `Missing value for --plugin|-p argument`);
        process.exit(1);
    }
    if (cli.flags.watch && cli.flags.onlypre) {
        console.error(utils_2.cerr `--watch and --onlypre cannot be enabled simultaneously`);
        process.exit(1);
    }
    if (cli.flags.production && cli.flags.onlypre) {
        console.error(utils_2.cerr `--production and --onlypre cannot be enabled simultaneously`);
        process.exit(1);
    }
    if (cli.flags.production && cli.flags.withYaml) {
        console.error(utils_2.cerr `--production and --withYaml cannot be enabled simultaneously`);
        process.exit(1);
    }
    if (cli.flags.threads !== null) {
        const t = parseInt(cli.flags.threads);
        if (isNaN(t)) {
            console.error(utils_2.cerr `Number of --threads|-t must be greater or equal to 0 `);
            process.exit(1);
            return;
        }
        cli.flags.threads = t;
    }
    if (cli.flags.verbose) {
        utils_2.enableDebug();
        utils_2.debug('Debugging enabled...');
    }
    if (cli.flags.production) {
        process.env.CPLACE_ENV = 'production';
    }
    const mainRepoPath = AssetsCompiler_1.AssetsCompiler.getMainRepoPath(process.cwd(), cli.flags.localonly);
    if (mainRepoPath === null) {
        console.error(utils_2.cerr `Failed to find path to main repository containing cf.cplace.platform plugin... Ensure that you are starting from the root directory of your cplace project.`);
        process.exit(1);
        return;
    }
    else if (path.basename(mainRepoPath) !== 'main' &&
        !cli.flags.onlypre &&
        !cli.flags.localonly) {
        console.warn(utils_2.cwarn `Sry main Repository is not called 'main' LESS Compilation might fail, please rename your folder to 'main'`);
    }
    // check node_modules folder is there as a leftover when switching back from a cplace/asc-local release branch
    if (!path.basename(process.cwd()).includes('main') &&
        fs.existsSync(path.join(process.cwd(), 'node_modules')) &&
        (CplaceVersion_1.CplaceVersion.get().major < 23 ||
            (CplaceVersion_1.CplaceVersion.get().major === 23 &&
                CplaceVersion_1.CplaceVersion.get().minor === 1))) {
        console.error(utils_2.cerr `Please remove node_modules folder from your project root. \n
        node_modules folder is not allowed in repos that are not main/cplace below release 23.2 \n 
        (-> ${path.join(process.cwd(), 'node_modules')})`);
        process.exit(1);
    }
    try {
        PackageVersion_1.PackageVersion.initialize(mainRepoPath);
        const plugins = cli.flags.plugin ? cli.flags.plugin.split(',') : [];
        const config = {
            rootPlugins: plugins,
            watchFiles: cli.flags.watch,
            onlyPreprocessing: cli.flags.onlypre,
            clean: cli.flags.clean,
            maxParallelism: !!cli.flags.threads
                ? cli.flags.threads
                : os.cpus().length - 1,
            localOnly: cli.flags.localonly,
            production: cli.flags.production,
            withYaml: cli.flags.withYaml,
            noParents: cli.flags.noparents || cli.flags.noParents,
            packagejson: cli.flags.packagejson,
            cplaceversion: cli.flags.cplaceversion,
        };
        console.log(utils_1.getAvailableStats());
        const assetsCompiler = new AssetsCompiler_1.AssetsCompiler(config, process.cwd());
        process.on('SIGTERM', () => {
            utils_2.debug('Shutting down...');
            assetsCompiler.shutdown().then(() => {
                process.exit(0);
            }, () => {
                process.exit(1);
            });
        });
        // Timeout to ensure flush of stdout
        assetsCompiler.start(updateDetails).then(() => {
            setTimeout(() => process.exit(0), 200);
        }, (reason) => {
            const message = reason instanceof Error ? reason.message : reason;
            console.error(utils_2.cerr `Failed to start assets compiler: ${message}`);
            if (utils_2.isDebugEnabled()) {
                console.error(reason);
            }
            setTimeout(() => process.exit(1), 200);
        });
    }
    catch (err) {
        console.error(utils_2.cerr `Failed to start assets compiler: ${err.message}`);
        if (utils_2.isDebugEnabled()) {
            console.error(err);
        }
        process.exit(1);
    }
}
function checkNodeVersion() {
    const nodeVersionUtils = new NodeUtils_1.NodeVersionUtils();
    if (CplaceVersion_1.CplaceVersion.get().major <= 5 && CplaceVersion_1.CplaceVersion.get().minor <= 18) {
        console.log(`⟲ cplaceVersion ${CplaceVersion_1.CplaceVersion.toString()} is less or equal to 5.18.0 -> assuming node version is correct`);
        return;
    }
    if (!nodeVersionUtils.versionsDefined()) {
        console.log('⟲ Failed to check node version, assuming correct version...');
        return;
    }
    if (nodeVersionUtils.strictVersionEqual()) {
        console.log(utils_2.cgreen `✓`, 'You are using a correct Node version!');
        return;
    }
    if (!nodeVersionUtils.majorVersionEqual()) {
        console.error(utils_2.cerr `You are using an incorrect major Node version!`);
        process.exit(1);
    }
    const assetsWarning = `Your assets might not be compiled correctly!`;
    if (!nodeVersionUtils.minorVersionEqual()) {
        console.warn(utils_2.cwarn `You are using an incorrect minor Node version! ${assetsWarning}`);
    }
    if (!nodeVersionUtils.patchVersionEqual()) {
        console.warn(utils_2.cwarn `You are using an incorrect patch Node version! ${assetsWarning}`);
    }
}
//# sourceMappingURL=index.js.map