//#region imports
import { Helpers } from 'tnp-core/lib';
import { _, crossPlatformPath } from 'tnp-core/lib';
import { CLASS } from 'typescript-class-helpers/lib';
import { HelpersTaon } from '../../helpers/helpers';
//#endregion
export class BaseCommandLineFeature {
    argsWithParams;
    methodNameToCall;
    cwd;
    __transformArgsBeforeResolvingParams__(args) {
        const transformaed = args.map(a => {
            return a
                .replace(`--copyTo`, '--copyto')
                .replace(`copyTo`, '--copyto')
                .replace(`copyto`, '--copyto');
        });
        return transformaed;
    }
    /**
     * first arg from args
     */
    get firstArg() {
        return _.first(this.args);
    }
    /**
     * last arg from args
     */
    get lastArg() {
        return _.last(this.args);
    }
    get project() {
        return this.__project;
    }
    set project(v) {
        // if (!v) {
        //   Helpers.error(
        //     `Command line cannot be executed on folder that is not know project.`,
        //     false,
        //     true,
        //   );
        // }
        this.__project = v;
    }
    get allParamsAfterFrameworName() {
        //#region @backendFunc
        return [
            `${_.kebabCase(this.classNameOfMethodToCall).toLowerCase()}:${this.methodNameToCall}`,
            ...(this.argsWithParams || '')?.split(' '),
        ].join(' ');
        //#endregion
    }
    constructor(argsWithParams, methodNameToCall, 
    /**
     * nearest project to cwd
     */
    project, 
    /**
     * process.cwd()
     */
    cwd, ins) {
        this.argsWithParams = argsWithParams;
        this.methodNameToCall = methodNameToCall;
        this.cwd = cwd;
        //#region @backend
        this.ins = ins;
        this.project = project;
        this.cwd = crossPlatformPath(cwd);
        //#region resolve params and args
        // this.project = Project.Current as Project;
        const className = CLASS.getNameFromObject(this);
        const methods = CLASS.getMethodsNames(this).filter(f => !f.startsWith('_'));
        // console.log({ className, methods })
        //#region methods names from prototype hack
        // const classFn = Object.getPrototypeOf(this).constructor;
        // console.log({ className, methods });
        // Object.defineProperty($Global.prototype.version, 'name', { value: 'version', writable: true });
        // HACK: to set name of global methods
        // TODO this will not survive minification
        // for (const classMethodsName of methods) {
        //   Object.defineProperty(classFn.prototype[classMethodsName], 'name', {
        //     value:
        //       classFn === '$Global' // TODO register alywas $Global as ''
        //         ? classMethodsName
        //         : `${className}.${classMethodsName}`,
        //     writable: false,
        //   });
        // }
        //#endregion
        const firstArg = _.first(argsWithParams.split(' '));
        const method = methods.find(m => m === firstArg);
        this.classNameOfMethodToCall = className;
        // console.log('className',className)
        if (method && !!className && !methodNameToCall) {
            // this prevents taon reset develop => to run: taon develop
            methodNameToCall = method;
            argsWithParams = argsWithParams.split(' ').slice(1).join(' ');
            this.argsWithParams = argsWithParams;
        }
        this.argsWithParams = argsWithParams || '';
        this.methodNameToCall = methodNameToCall;
        this.params =
            require('minimist')(this.__transformArgsBeforeResolvingParams__(argsWithParams.split(' '))) || {};
        delete this.params['_']; // TODO quickfix
        const allArgsToClear = Object.keys(this.params);
        // console.log(this.params)
        // for (const deleteArgKey of allArgsToClear) {
        //   delete this.params[deleteArgKey];
        // }
        // console.log({ clearArgs: allArgsToClear })
        // TODO QUIKC_FIX for taon production
        // prettier-ignore
        this.args = HelpersTaon.cliTool.removeArgsFromCommand(argsWithParams, allArgsToClear)
            .split(' ')
            .filter(f => !!f);
        Helpers.runSyncOrAsync({
            functionFn: this.__initialize__,
            arrayOfParams: [this.params, this.project, this.args],
            context: this,
        }).then(() => {
            if (methodNameToCall) {
                if (_.isFunction(this[methodNameToCall])) {
                    this[methodNameToCall]();
                }
                else {
                    Helpers.error(`Class ${CLASS.getName(this)} doesn't have method '${methodNameToCall}'`, false, true);
                }
            }
            else {
                this._();
            }
        });
        //#endregion
        //#endregion
    }
    _exit(code = 0) {
        if (_.isFunction(this.project?.ins?.exitProgramCleaningFn)) {
            this.project.ins.exitProgramCleaningFn().finally(() => {
                process.exit(code);
            });
        }
        else {
            process.exit(code);
        }
    }
    __initialize__() { }
    _tryResolveChildIfInsideArg() {
        const { resolved, clearedCommand, } = // @ts-ignore
         HelpersTaon.cliTool.resolveItemFromArgsBegin(this.args, arg => this.project.getChildBy(arg.replace(/\/$/, '')));
        this.project = resolved ? resolved : this.project;
        this.args = resolved ? clearedCommand.split(' ') : this.args;
    }
}
//# sourceMappingURL=base-command-line-feature.js.map