import { IPackageJson } from '@rushstack/node-core-library';
import { ITerminal } from '@rushstack/terminal';

/**
 * The extractor configuration for individual dependencies.
 *
 * @public
 */
export declare interface IExtractorDependencyConfiguration {
    /**
     * The name of dependency
     */
    dependencyName: string;
    /**
     * The semver version range of dependency
     */
    dependencyVersionRange: string;
    /**
     * A list of glob patterns to exclude when extracting this dependency. If a path is
     * matched by both "patternsToInclude" and "patternsToExclude", the path will be
     * excluded. If undefined, no paths will be excluded.
     */
    patternsToExclude?: string[];
    /**
     * A list of glob patterns to include when extracting this dependency. If a path is
     * matched by both "patternsToInclude" and "patternsToExclude", the path will be
     * excluded. If undefined, all paths will be included.
     */
    patternsToInclude?: string[];
}

/**
 * The extractor-metadata.json file format.
 *
 * @public
 */
export declare interface IExtractorMetadataJson {
    /**
     * The name of the main project the extraction was performed for.
     */
    mainProjectName: string;
    /**
     * A list of all projects that were extracted.
     */
    projects: IProjectInfoJson[];
    /**
     * A list of all links that are part of the extracted project.
     */
    links: ILinkInfo[];
    /**
     * A list of all files that are part of the extracted project.
     */
    files: string[];
}

/**
 * Options that can be provided to the extractor.
 *
 * @public
 */
export declare interface IExtractorOptions {
    /**
     * A terminal to log extraction progress.
     */
    terminal: ITerminal;
    /**
     * The main project to include in the extraction operation.
     */
    mainProjectName: string;
    /**
     * The source folder that copying originates from.  Generally it is the repo root folder.
     */
    sourceRootFolder: string;
    /**
     * The target folder for the extraction.
     */
    targetRootFolder: string;
    /**
     * Whether to overwrite the target folder if it already exists.
     */
    overwriteExisting: boolean;
    /**
     * The desired path to be used when archiving the target folder. Supported file extensions: .zip.
     */
    createArchiveFilePath?: string;
    /**
     * Whether to skip copying files to the extraction target directory, and only create an extraction
     * archive. This is only supported when {@link IExtractorOptions.linkCreation} is 'script' or 'none'.
     */
    createArchiveOnly?: boolean;
    /**
     * The pnpmfile configuration if using PNPM, otherwise `undefined`. The configuration will be used to
     * transform the package.json prior to extraction.
     *
     * @remarks
     * When Rush subspaces are enabled, this setting applies to `default` subspace only.  To configure
     * each subspace, use the {@link IExtractorOptions.subspaces} array instead.  The two approaches
     * cannot be combined.
     */
    transformPackageJson?: (packageJson: IPackageJson) => IPackageJson;
    /**
     * If dependencies from the "devDependencies" package.json field should be included in the extraction.
     */
    includeDevDependencies?: boolean;
    /**
     * If files ignored by the .npmignore file should be included in the extraction.
     */
    includeNpmIgnoreFiles?: boolean;
    /**
     * The folder where the PNPM "node_modules" folder is located. This is used to resolve packages linked
     * to the PNPM virtual store.
     *
     * @remarks
     * When Rush subspaces are enabled, this setting applies to `default` subspace only.  To configure
     * each subspace, use the {@link IExtractorOptions.subspaces} array instead.  The two approaches
     * cannot be combined.
     */
    pnpmInstallFolder?: string;
    /**
     * The link creation mode to use.
     * "default": Create the links while copying the files; this is the default behavior. Use this setting
     * if your file copy tool can handle links correctly.
     * "script": A Node.js script called create-links.js will be written to the target folder. Use this setting
     * to create links on the server machine, after the files have been uploaded.
     * "none": Do nothing; some other tool may create the links later, based on the extractor-metadata.json file.
     */
    linkCreation?: LinkCreationMode;
    /**
     * The path to the generated link creation script. This is only used when {@link IExtractorOptions.linkCreation}
     * is 'script'.
     */
    linkCreationScriptPath?: string;
    /**
     * An additional folder containing files which will be copied into the root of the extraction.
     */
    folderToCopy?: string;
    /**
     * Configurations for individual projects, keyed by the project path relative to the sourceRootFolder.
     */
    projectConfigurations: IExtractorProjectConfiguration[];
    /**
     * Configurations for individual dependencies.
     */
    dependencyConfigurations?: IExtractorDependencyConfiguration[];
    /**
     * When using Rush subspaces, this setting can be used to provide configuration information for each
     * individual subspace.
     *
     * @remarks
     * To avoid confusion, if this setting is used, then the {@link IExtractorOptions.transformPackageJson} and
     * {@link IExtractorOptions.pnpmInstallFolder} settings must not be used.
     */
    subspaces?: IExtractorSubspace[];
}

/**
 * The extractor configuration for individual projects.
 *
 * @public
 */
export declare interface IExtractorProjectConfiguration {
    /**
     * The name of the project.
     */
    projectName: string;
    /**
     * The absolute path to the project.
     */
    projectFolder: string;
    /**
     * A list of glob patterns to include when extracting this project. If a path is
     * matched by both "patternsToInclude" and "patternsToExclude", the path will be
     * excluded. If undefined, all paths will be included.
     */
    patternsToInclude?: string[];
    /**
     * A list of glob patterns to exclude when extracting this project. If a path is
     * matched by both "patternsToInclude" and "patternsToExclude", the path will be
     * excluded. If undefined, no paths will be excluded.
     */
    patternsToExclude?: string[];
    /**
     * The names of additional projects to include when extracting this project.
     */
    additionalProjectsToInclude?: string[];
    /**
     * The names of additional dependencies to include when extracting this project.
     */
    additionalDependenciesToInclude?: string[];
    /**
     * The names of additional dependencies to exclude when extracting this project.
     */
    dependenciesToExclude?: string[];
}

/**
 * The extractor subspace configurations
 *
 * @public
 */
export declare interface IExtractorSubspace {
    /**
     * The subspace name
     */
    subspaceName: string;
    /**
     * The folder where the PNPM "node_modules" folder is located. This is used to resolve packages linked
     * to the PNPM virtual store.
     */
    pnpmInstallFolder?: string;
    /**
     * The pnpmfile configuration if using PNPM, otherwise undefined. The configuration will be used to
     * transform the package.json prior to extraction.
     */
    transformPackageJson?: (packageJson: IPackageJson) => IPackageJson;
}

/**
 * Represents a symbolic link.
 *
 * @public
 */
export declare interface ILinkInfo {
    /**
     * The type of link that was encountered.
     */
    kind: 'fileLink' | 'folderLink';
    /**
     * The path to the link, relative to the root of the extractor output folder.
     */
    linkPath: string;
    /**
     * The target that the link points to.
     */
    targetPath: string;
}

/**
 * Part of the extractor-matadata.json file format. Represents an extracted project.
 *
 * @public
 */
export declare interface IProjectInfoJson {
    /**
     * The name of the project as specified in its package.json file.
     */
    projectName: string;
    /**
     * This path is relative to the root of the extractor output folder
     */
    path: string;
}

/**
 * The mode to use for link creation.
 *
 * @public
 */
export declare type LinkCreationMode = 'default' | 'script' | 'none';

/**
 * Manages the business logic for the "rush deploy" command.
 *
 * @public
 */
export declare class PackageExtractor {
    /**
     * Get a list of files that would be included in a package created from the provided package root path.
     *
     * @beta
     */
    static getPackageIncludedFilesAsync(packageRootPath: string): Promise<string[]>;
    /**
     * Extract a package using the provided options
     */
    extractAsync(options: IExtractorOptions): Promise<void>;
    private static _normalizeOptions;
    private _performExtractionAsync;
    /**
     * Recursively crawl the node_modules dependencies and collect the result in IExtractorState.foldersToCopy.
     */
    private _collectFoldersAsync;
    private _applyDependencyFilters;
    /**
     * Copy one package folder to the extractor target folder.
     */
    private _extractFolderAsync;
    /**
     * Write the common/deploy/deploy-metadata.json file.
     */
    private _writeExtractorMetadataAsync;
    private _makeBinLinksAsync;
    private _writeCreateLinksScriptAsync;
}

export { }
