/**
 * @author        Vivek M. Chawla <@VivekMChawla>
 * @copyright     2019, Vivek M. Chawla / Salesforce. All rights reserved.
 * @license       BSD-3-Clause For full license text, see the LICENSE file in the repo root or
 *                `https://opensource.org/licenses/BSD-3-Clause`
 * @file          packages/generator/src/generator.ts
 * @summary       Exports `SfdxFalconGenerator` for use with custom Yeoman generators.
 * @description   Exports an abstract class that extends Yeoman's `Generator` class, adding
 *                customized support for SFDX-Falcon specific tools and capabilities.
 */
import * as Generator from 'yeoman-generator';
import { ExternalContext } from '@sfdx-falcon/builder';
import { SfdxEnvironment } from '@sfdx-falcon/environment';
import { SfdxFalconInterview } from '@sfdx-falcon/interview';
import { SfdxFalconResult } from '@sfdx-falcon/status';
import { GeneratorStatus } from '@sfdx-falcon/status';
import { GeneratorOptions } from '@sfdx-falcon/command';
import { SfdxEnvironmentRequirements } from '@sfdx-falcon/environment';
import { SfdxFalconTableData } from '@sfdx-falcon/status';
import { ConfirmationAnswers } from '@sfdx-falcon/types';
import { JsonMap } from '@sfdx-falcon/types';
/**
 * Interface. Collection of objects that represent the Answers that will be leveraged by an
 * `SfdxFalconGenerator`.
 */
export interface Answers<T extends JsonMap> {
    /** Required. The set of default answers for the Interview of an `SfdxFalconGenerator`. */
    default: T;
    /** Required. The set of answers provided by the user for the Interview of an `SfdxFalconGenerator`. */
    user: T;
    /** Required. The set of final answers for the Interview of an `SfdxFalconGenerator`. In other words, the merging of User and Default answers in case the user did not supply some answers. */
    final: T;
    /** Required. Special set of answers. Provides a means to send meta values (usually template tags) to EJS templates. */
    meta: T;
    /** Required. The set of answers provided when the user is asked to proceed/retry/abort something. */
    confirmation: ConfirmationAnswers;
}
/**
 * Interface. Collection of message strings that are displayed at various times during the execution
 * of an `SfdxFalconGenerator`.
 */
export interface GeneratorMessages {
    /** Required. Message that will be displayed by the opening Banner when the generator is loaded. */
    opening: string;
    /** Required. Message shown to the user before the interview starts during the prompting() run-loop function. */
    preInterview: string;
    /** Required. Message shown to the user to help them decide to exit the prompting() run-loop function. */
    confirmation: string;
    /** Required. Message shown to the user after the interview ends but before the prompting() run-loop function exits. */
    postInterview: string;
    /** Required. Message that will be displayed by the `end()` run-loop function upon successful completion of the Generator. */
    success: string;
    /** Required. Message that will be displayed by the `end()` run-loop function upon failure of the Generator. */
    failure: string;
    /** Required. Message that will be displayed by the `end()` run-loop function upon partial success of the Generator.  */
    warning: string;
}
/**
 * Interface. Collection of requirements for the initialization process of an `SfdxFalconGenerator`.
 */
export interface GeneratorRequirements {
    gitEnvReqs: object;
    sfdxEnvReqs: SfdxEnvironmentRequirements;
    localEnvReqs: object;
}
/**
 * Interface. Collection of status `boolean` variables that reflect the status of various Yeoman
 * run-loop functions.
 */
export interface RunLoopStatus {
    /** Required. Indicates that the `initializing()` run-loop function has completed successfully. */
    initializingComplete: boolean;
    /** Required. Indicates that the `prompting()` run-loop function has completed successfully. */
    promptingComplete: boolean;
    /** Required. Indicates that the `configuring()` run-loop function has completed successfully. */
    configuringComplete: boolean;
    /** Required. Indicates that the `writing()` run-loop function has completed successfully. */
    writingComplete: boolean;
    /** Required. Indicates that the `install()` run-loop function has completed successfully. */
    installComplete: boolean;
    /** Required. Indicates that the `end()` run-loop function completed successfully. */
    endComplete: boolean;
}
/**
 * @class       SfdxFalconGenerator
 * @extends     Generator
 * @summary     Abstract base class class for building Yeoman Generators for SFDX-Falcon commands.
 * @description Classes that extend `SfdxFalconGenerator` must provide a type parameter to
 *              ensure that the "answers" family of member variables (`defaultAnswers`,
 *              `userAnswers`, `metaAnswers`, and `finalAnswers`) has the appropriate interface
 *              type which defines the answers that are relevant to a concrete child class.
 * @public @abstract
 */
export declare abstract class SfdxFalconGenerator<T extends JsonMap> extends Generator {
    /** Debug namespace of the derived class. Makes it easier to debug superclass operations when extending `SfdxFalconGenerator`. */
    protected readonly dbgNs: string;
    /** Name of the CLI command that kicked off this Generator. */
    protected readonly commandName: string;
    /** External Context describing an instance of the derived class. Used by Builder-derived classes. */
    protected readonly extCtx: ExternalContext;
    /** Reference to the package manifest (`package.json`) of the module that owns the class that implements the command entrypoint. */
    protected readonly packageJson: JsonMap;
    /** Version of the plugin that's running this Generator. Taken dynamically from `package.json`. */
    protected readonly pluginVersion: string;
    /** Custom `falcon` options key from `package.json`. Can be used to read package-global settings that a plugin developer chooses to add to `package.json`. */
    protected readonly falcon: JsonMap;
    /** Specifies the various messages used by this Generator. */
    protected readonly generatorMessages: GeneratorMessages;
    /** Tracks the name (type) of Generator being run, eg. `clone-appx-package-project`. */
    protected readonly generatorType: string;
    /** Tracks the path to the of the source file containing the Generator being run, eg `../../generators`. */
    protected readonly generatorPath: string;
    /** Used to keep track of status and to return messages to the caller. */
    protected readonly generatorStatus: GeneratorStatus;
    /** Used to keep track of status and to return messages to the caller. */
    protected readonly generatorResult: SfdxFalconResult;
    /** Determines which initialization tasks are performed during the Default Initialization process. */
    protected readonly generatorReqs: GeneratorRequirements;
    /** Tracks the status of various run-loop functions. */
    protected readonly runLoopStatus: RunLoopStatus;
    /** Collection of objects that represent the Answers to questions that will be asked during the Interview. */
    protected readonly answers: Answers<T>;
    /** Used to share data between the Generator, Inqurirer Prompts, and Listr Tasks. */
    protected readonly sharedData: object;
    /** Holds the `SfdxFalconInterview` object that will be run during the `prompting()` run-loop function. */
    protected userInterview: SfdxFalconInterview<T>;
    /** Represents the SFDX Environment. */
    protected sfdxEnv: SfdxEnvironment;
    /**
     * @constructs  SfdxFalconGenerator
     * @param       {string|string[]} args Required. Array of arguments that are
     *              passed to this generator by Yeoman if the generator is being
     *              invoked from the command line. Passed directly through to
     *              the superclass constructor without modification.
     * @param       {GeneratorOptions}  opts Required. Object containing options
     *              that help specify how a specific generator is run. These
     *              options are set when external code uses a Yeoman Environment
     *              to `run()` a Generator that's derived from this class.
     * @description Constructs an `SfdxFalconGenerator` object.
     * @public
     */
    constructor(args: string | string[], opts: GeneratorOptions, reqs: GeneratorRequirements);
    abstract initializing(): Promise<void>;
    abstract prompting(): Promise<void>;
    abstract configuring(): Promise<void>;
    abstract writing(): Promise<void>;
    abstract install(): Promise<void>;
    abstract end(): Promise<void>;
    /**
     * @method      _showOpener
     * @returns     {Promise<void>}
     * @description Shows an opening message when the `initializing` run-loop
     *              function is executed. Uses the string from
     *              `this.generatorMessage.opening` as the source of the message
     *              contents. Can be overridden by derived class to customize the
     *              opener behavior.
     * @protected @async
     */
    protected _showOpener(): Promise<void>;
    /**
     * @method      __initializing
     * @returns     {Promise<void>}
     * @description STEP ONE in the Yeoman run-loop.  Intended to be executed as
     *              part of Yeoman's `initializing` run-loop priority.  Will call
     *              the matching single-underscore method `_initializing()` from
     *              the derived class after executing logic that's specialized
     *              for `SfdxFalconGenerator` based Generators. This method must
     *              be called by the `initializing()` method that's implemented
     *              by the dervived class.
     * @protected @async
     */
    protected __initializing(): Promise<void>;
    /**
     * @method      __prompting
     * @returns     {Promise<void>}
     * @description STEP TWO in the Yeoman run-loop.  Interviews the User to get
     *              information needed by the `writing` and `installing` phases.
     *              Intended to be executed as part of Yeoman's `prompting`
     *              run-loop priority.  Will call the matching single-underscore
     *              method `_prompting()` from the derived class after executing
     *              logic that's specialized for `SfdxFalconGenerator` based
     *              Generators. This method must be called by the `prompting()`
     *              method that's implemented by the dervived class.
     * @protected @async
     */
    protected __prompting(): Promise<void>;
    /**
     * @method      __configuring
     * @returns     {void}
     * @description STEP THREE in the Yeoman run-loop. Perform any pre-install
     *              configuration steps based on the answers provided by the User.
     *              Intended to be executed as part of Yeoman's `configuring`
     *              run-loop priority.  Will call the matching single-underscore
     *              method `_configuring()` from the derived class after executing
     *              logic that's specialized for `SfdxFalconGenerator` based
     *              Generators. this method must be called by the `configuring()`
     *              method that's implemented by the dervived class.
     * @protected @async
     */
    protected __configuring(): Promise<void>;
    /**
     * @method      __writing
     * @returns     {Promise<void>}
     * @description __STEP FOUR in the Yeoman run-loop.__ Typically, this is where
     *              you perform filesystem writes, git clone operations, etc.
     *              Intended to be executed as part of Yeoman's `writing` run-loop
     *              priority.  Will call the matching single-underscore method
     *              `_writing()` from the derived class after executing logic
     *              that's specialized for `SfdxFalconGenerator` based Generators.
     *              This method must] be called by the `writing()` method that's
     *              implemented by the dervived class.
     * @protected @async
     */
    protected __writing(): Promise<void>;
    /**
     * @method      install
     * @returns     {Promise<void>}
     * @description __STEP FIVE in the Yeoman run-loop.__ Typically, this is where
     *              you perform operations that must happen AFTER files are
     *              written to disk. For example, if the `writing` step downloaded
     *              an app to install, the `install` step would run the
     *              installation. Intended to be executed as part of Yeoman's
     *              `install` run-loop priority.  Will call the matching
     *              single-underscore method `_install()` from the derived class
     *              after executing logic that's specialized for `SfdxFalconGenerator`
     *              based Generators. This method must be called by the `install()`
     *              method that's implemented by the dervived class.
     * @protected @async
     */
    protected __install(): Promise<void>;
    /**
     * @method      __end
     * @returns     {Promise<void>}
     * @description __STEP SIX in the Yeoman run-loop.__ This is the FINAL step
     *              that Yeoman runs and it gives us a chance to do any post-Yeoman
     *              updates and/or cleanup. Intended to be executed as part of the
     *              `end` run-loop priority.  Will call the matching single-underscore
     *              method `_end()` from the derived class after executing logic
     *              that's specialized for `SfdxFalconGenerator` based Generators.
     *              This method must be called by the `end()` method that's
     *              implemented by the dervived class.
     * @protected @async
     */
    protected __end(): Promise<void>;
    /** Builds a complete `SfdxFalconInterview` object, which may include zero or more confirmation groupings. */
    protected abstract _buildInterview(): SfdxFalconInterview<T>;
    /** Creates Interview Answers table data. Can be used to render an `SfdxFalconTable` object. */
    protected abstract _buildInterviewAnswersTableData(userAnswers: T): Promise<SfdxFalconTableData>;
    /** STEP ONE in the Yeoman run-loop. Uses Yeoman's "initializing" run-loop priority. */
    protected abstract _initializing(): Promise<void>;
    /** STEP TWO in the Yeoman run-loop. Interviews the User to get information needed by the `_writing()` and `_install()` functions. */
    protected abstract _prompting(): Promise<void>;
    /** STEP THREE in the Yeoman run-loop. Perform any pre-install configuration steps based on the answers provided by the User. */
    protected abstract _configuring(): Promise<void>;
    /** STEP FOUR in the Yeoman run-loop. Typically, this is where you perform filesystem writes, git clone operations, etc. */
    protected abstract _writing(): Promise<void>;
    /** STEP FIVE in the Yeoman run-loop. Typically, this is where you perform operations that must happen AFTER files are written to disk. For example, if the `_writing()` step downloaded an app to install, the `_install()` step would run the installation. */
    protected abstract _install(): Promise<void>;
    /** STEP SIX in the Yeoman run-loop. This is the FINAL step that Yeoman runs and it gives us a chance to do any post-Yeoman updates and/or cleanup. */
    protected abstract _end(): Promise<void>;
}
