"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.commandBase = void 0;
const tslib_1 = require("tslib");
require("reflect-metadata");
const path = require("path");
const inversify_1 = require("inversify");
const core_1 = require("@oclif/core");
const nodeUtil = require("util");
const fs = require("fs");
const child_process_1 = require("child_process");
const codiac_common_1 = require("@codiac.io/codiac-common");
const codiac_ops_common_1 = require("@codiac.io/codiac-ops-common");
const entities_1 = require("../ops/entities");
const data_1 = require("../ops/data");
const read_stdin_1 = require("../read-stdin");
const INTERFACES_CLI_1 = require("../ops/INTERFACES_CLI");
class commandBase extends core_1.Command {
    constructor() {
        super(...arguments);
        this.__localConfigIsLoaded = false;
        this.execAsync = nodeUtil.promisify(child_process_1.exec); // antiquated nastiness
        this.copyAsync = nodeUtil.promisify(fs.copyFile); // antiquated nastiness
    }
    /** Override method because oclif's exit is throwing error:
     * ```typescript
     * "TypeError [ERR_INVALID_ARG_TYPE]: The 'code' argument must be of type number. Received type string ('EEXIT')"
     * ``` */
    exit(exitCode) {
        process.exit(exitCode);
    }
    readStdin() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                try {
                    // this.pipedInput = await read(process.stdin);
                    this.pipedInput = yield (0, read_stdin_1.default)();
                    resolve();
                }
                catch (err) {
                    reject(err);
                }
            }));
        });
    }
    // ------------------------------------
    // Lazy-loaded properties 
    // 
    // (this is an interim step for now, 
    // while commands are refactored 
    // to use ioc as needed instead of commandBase properties)
    // ------------------------------------
    get ioc() {
        if (this.__ioc === undefined) {
            this.__ioc = new inversify_1.Container();
        }
        return this.__ioc;
    }
    ;
    // ------------------------------------
    // IOC WRAPPER PROPERTIES
    // ------------------------------------
    get logger() {
        if (this.__logger === undefined) {
            this.__logger = this.ioc.get(codiac_common_1.INTERFACES.IBetterLogger);
        }
        return this.__logger;
    }
    ;
    get cliEnviro() {
        if (this._cliEnviro_backer === undefined) {
            this._cliEnviro_backer = this.ioc.get(entities_1.CliEnviro);
        }
        return this._cliEnviro_backer;
    }
    get _cfgRepo() {
        if (this.__cfgRepo === undefined) {
            this.__cfgRepo = this.ioc.get(data_1.CliGlobalConfigRepo);
        }
        return this.__cfgRepo;
    }
    /** Deprecated: use ioc instead.  This getter Lazyloads from ioc. */
    get _cliCfg() {
        if (this.__cliCfg === undefined) {
            this.__cliCfg = this.ioc.get(entities_1.CliConfig);
        }
        return this.__cliCfg;
    }
    /** Deprecated: use ioc instead.  This getter Lazyloads from ioc. */
    get _ui() {
        if (this.__ui === undefined) {
            this.__ui = this.ioc.get(INTERFACES_CLI_1.INTERFACES_CLI.IUserInputProvider);
        }
        return this.__ui;
    }
    /** Deprecated: use ioc instead.  This getter Lazyloads from ioc. */
    get _styler() {
        if (this.__styler === undefined) {
            this.__styler = this.ioc.get(INTERFACES_CLI_1.INTERFACES_CLI.IOutputStyler);
        }
        return this.__styler;
    }
    /** Fully qualified path to the app config folder on the local machine. */
    get localConfigPath() {
        if (this.__localConfigPath === undefined) {
            this.__localConfigPath = this.cliEnviro.localProgramFolder;
        }
        return this.__localConfigPath;
    }
    /** The Codiac Local config overrides (shared with the relay). */
    get localConfig() {
        if (this.__localConfigIsLoaded !== true) {
            let localOverridesPathname = path.posix.join(this.localConfigPath, "codiac-local.json");
            this.__localConfig = codiac_ops_common_1.JsonUtils.deserializeJsonFile(localOverridesPathname);
            this.__localConfigIsLoaded = true;
        }
        return this.__localConfig;
    }
    // async run(): Promise<void> {
    //   return new Promise<void>(async (resolve,reject) => {
    //     try {
    //       // My shit here....
    //       resolve();
    //     } catch (err) {
    //       reject(err);
    //     }
    //   });
    // }
    /** Call this from the catch block of your command handler.
     * Writes the error message appropriately to the console,
     * minding stderr and stdout as required. */
    handleError(err) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        if (((err === null || err === void 0 ? void 0 : err.code) == "EEXIT") && (((_a = err.oclif) === null || _a === void 0 ? void 0 : _a.exit) === 0)) {
            this.logger.debug("Operation cancelled.");
        }
        else {
            if (err.stdout || err.stderr) {
                this.logger.error(`Operation failed! ${(_b = err.name) !== null && _b !== void 0 ? _b : ""} ${(_c = err.message) !== null && _c !== void 0 ? _c : ""}`, { stdout: err.stdout, stderr: err.stderr, stack: err.stack });
            }
            else {
                this.logger.error(`Operation failed! ${(_d = err.name) !== null && _d !== void 0 ? _d : ""} ${(_e = err.message) !== null && _e !== void 0 ? _e : ""}`, err.stack);
                this._ui.userMessage(this._styler.colorCritical("Operation failed! ").concat((_f = err.message) !== null && _f !== void 0 ? _f : ""));
            }
            // need to output stderr for pipelines
            if (!process.stdin.isTTY) {
                (err === null || err === void 0 ? void 0 : err.message) ? process.stderr.write(`Operation failed! ${(_g = err.name) !== null && _g !== void 0 ? _g : ""} ${(_h = err.message) !== null && _h !== void 0 ? _h : ""}`) : process.stderr.write("Error, see logs for details");
            }
        }
        // this.exit(err.code ?? 1);
        process.exit((_j = err.code) !== null && _j !== void 0 ? _j : 1);
    }
}
exports.commandBase = commandBase;
commandBase.dependencyTargetingFlags = {
    only: core_1.Flags.boolean({ char: 'o', required: false, description: 'Applies the command only the sourced dependencies selected from a prompt. Quits if no dependencies are currently sourced.' }),
    includeDeps: core_1.Flags.boolean({ char: 'i', required: false, description: 'Also performs the operation on any currently source dependencies.' })
};
commandBase.dependencyTargetingArgs = {
    name: core_1.Args.string({ require: false, description: 'The official unique name of a currently sourced dependency.  Applies the command to ONLY this sourced dependency.' })
};
/** Flags that can be available to multiple commands.
 *  Support them in a command by extending the flags object with this property using a spread operator.
 * eg:  static flags = { ...commandBase.globalFlags, myflag: flags.boolean(yadayada) }
 */
commandBase.globalFlags = {
    as: core_1.Flags.string({ description: 'Fires this command with an argument list that was previously remembered using the --rememberAs flag.' }),
    remember: core_1.Flags.boolean({ description: 'Saves the arguments, so they are invoked as defaults whenever this command gets called.' }),
    rememberAs: core_1.Flags.string({ description: 'Saves the given argument list so that it can be called by name.' }),
    unremember: core_1.Flags.string({ description: 'Administrative only: DOES NOT fire the actual command.  Simply clears the arguments that were previously stored under the given name (use "--unRemember default" to clear default argument list memorized with the --remember flag).' }),
    withoutdefaults: core_1.Flags.boolean({ description: "Prevents any relevant saved defaults from being invoked for this call." }),
    verbose: core_1.Flags.boolean({ char: 'v', description: 'Renders additional logging levels (detail, trace, and debug) to the console output.' })
};
//# sourceMappingURL=command-base.js.map