/**
 * @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/project-generator.ts
 * @summary       Exports `SfdxFalconProjectGenerator` for use with custom Yeoman generators that
 *                focus on standing up local projects.
 * @description   Exports an abstract class that extends the SFDX-Falcon Library's `SfdxFalconGenerator`
 *                class, adding customized support for tools and capabilities that make it easier
 *                to stand up a local git-based project.
 */
import * as Generator from 'yeoman-generator';
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 { JsonMap } from '@sfdx-falcon/types';
import { StyledMessage } 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;
    /** Optional. Special set of answers. Provides a means to send meta values (usually template tags) to EJS templates. */
    meta?: T;
}
/**
 * Interface. Collection of message strings that are displayed at various times during the execution
 * of an `SfdxFalconGenerator`.
 */
export interface GeneratorMessage {
    /** Required. Message shown to the user before exiting the initializing() run-loop function. */
    confirmation: string;
    /** Required. Message that will be displayed by the yosay "Yeoman" ASCII art when the generator is loaded. */
    opening: 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 {
    /** Name of the CLI command that kicked off this Generator. */
    protected readonly commandName: string;
    /** 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 generatorMessage: GeneratorMessage;
    /** 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);
    /**
     * @method      initializing
     * @returns     {Promise<void>}
     * @description STEP ONE in the Yeoman run-loop.  Uses Yeoman's "initializing"
     *              run-loop priority.  This is a "default" implementation and
     *              should work for most SFDX-Falcon use cases. It must be called
     *              from inside the initializing() method of the child class.
     * @public @async
     */
    /**
     * @method      prompting
     * @param       {StyledMessage} [preInterviewMessage] Optional. Message to
     *              display to the user before the Interview starts.
     * @param       {StyledMessage} [postInterviewMessage]  Optional. Message to
     *              display to the user after the Interview ends.
     * @returns     {Promise<void>}
     * @description STEP TWO in the Yeoman run-loop. Interviews the User to get
     *              information needed by the "writing" and "installing" phases.
     *              This is a "default" implementation and should work for most
     *              SFDX-Falcon use cases. It must be called from inside the
     *              prompting() method of the child class.
     * @public @async
     */
    prompting(preInterviewMessage?: StyledMessage, postInterviewMessage?: StyledMessage): 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.
     *              This is a "default" implementation and should work for most
     *              SFDX-Falcon use cases. It must be called from inside the
     *              configuring() method of the child class.
     * @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.
     *              This is a "default" implementation and should work for most
     *              SFDX-Falcon use cases. It must be called from inside the
     *              writing() method of the child class.
     * @public @async
     */
    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. This is a "default" implementation and should
     *              work for most SFDX-Falcon use cases. It must be called from
     *              inside the install() method of the child class.
     * @public @async
     */
    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. This is a "default" implementation
     *              and should work for most SFDX-Falcon use cases. It must be
     *              called from inside the end() method of the child class.
     * @public @async
     */
    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>;
    /**
     * @method      _cloneRepository
     * @returns     {Promise<string>} Local path into which the Git Repository
     *              was cloned. If the clone operation is unsuccessful, this
     *              will return an empty string.
     * @description Clones a remote Git Repository per information specified
     *              during by the command and/or during their interview. Returns
     *              the local path to which the Git Repository was cloned, or
     *              an empty string otherwise.
     * @protected @async
     */
    /**
     * @method      _executeInitializationTasks
     * @returns     {Promise<void>}
     * @description Runs a series of initialization tasks using the Listr UX/Task
     *              Runner module.  Listr provides a framework for executing tasks
     *              while also providing an attractive, realtime display of task
     *              status (running, successful, failed, etc.).
     * @protected @async
     */
    /**
     * @method      _finalizeGitActions
     * @param       {string}  destinationRoot Required.
     * @param       {boolean} isInitializingGit Required.
     * @param       {string}  gitRemoteUri  Required.
     * @param       {string}  projectAlias  Required.
     * @returns     {Promise<void>}
     * @description Intended to run after _finalizeProjectCreation() during the
     *              Yeoman "writing" phase.  Initializes local Git repo, and will
     *              even try to attach a Git remote if specified by the user.
     * @protected @async
     */
    /**
     * @method      _finalizeProjectCloning
     * @returns     {boolean} Returns FALSE if the project was aborted.
     * @description Intended to run after the Yeoman "writing" phase.  Has logic
     *              that ensures the Generator wasn't aborted, and then carries
     *              out finalization tasks that are generic to "cloning"
     *              Generators. Returns a boolean so the calling class can decide
     *              whether or not to perform additional actions.
     * @protected
     */
    protected _finalizeProjectCloning(): boolean;
    /**
     * @method      _finalizeProjectCreation
     * @returns     {boolean} Returns FALSE if the project was aborted.
     * @description Intended to run after the Yeoman "writing" phase.  Has logic
     *              that ensures the Generator wasn't aborted, and then carries
     *              out finalization tasks that are generic to "creation"
     *              Generators. Returns a boolean so the calling class can decide
     *              whether or not to perform additional actions.
     * @protected
     */
    protected _finalizeProjectCreation(): boolean;
}
