"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ListAction = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
const terminal_1 = require("@rushstack/terminal");
const BaseRushAction_1 = require("./BaseRushAction");
const VersionPolicy_1 = require("../../api/VersionPolicy");
const SelectionParameterSet_1 = require("../parsing/SelectionParameterSet");
class ListAction extends BaseRushAction_1.BaseRushAction {
    constructor(parser) {
        super({
            actionName: 'list',
            summary: 'List package information for all projects in the repo',
            documentation: 'List package names, and optionally version (--version) and ' +
                'path (--path) or full path (--full-path), for projects in the ' +
                'current rush config.',
            parser,
            safeForSimultaneousRushProcesses: true
        });
        this._version = this.defineFlagParameter({
            parameterLongName: '--version',
            parameterShortName: '-v',
            description: 'If this flag is specified, the project version will be ' +
                'displayed in a column along with the package name.'
        });
        this._path = this.defineFlagParameter({
            parameterLongName: '--path',
            parameterShortName: '-p',
            description: 'If this flag is specified, the project path will be ' +
                'displayed in a column along with the package name.'
        });
        this._fullPath = this.defineFlagParameter({
            parameterLongName: '--full-path',
            description: 'If this flag is specified, the project full path will ' +
                'be displayed in a column along with the package name.'
        });
        this._detailedFlag = this.defineFlagParameter({
            parameterLongName: '--detailed',
            description: 'For the non --json view, if this flag is specified, ' +
                'include path (-p), version (-v) columns along with ' +
                "the project's applicable: versionPolicy, versionPolicyName, " +
                'shouldPublish, reviewPolicy, and tags fields.'
        });
        this._jsonFlag = this.defineFlagParameter({
            parameterLongName: '--json',
            description: 'If this flag is specified, output will be in JSON format.'
        });
        this._selectionParameters = new SelectionParameterSet_1.SelectionParameterSet(this.rushConfiguration, this, {
            gitOptions: {
                // Include lockfile processing since this expands the selection, and we need to select
                // at least the same projects selected with the same query to "rush build"
                includeExternalDependencies: true,
                // Disable filtering because rush-project.json is riggable and therefore may not be available
                enableFiltering: false
            },
            includeSubspaceSelector: false,
            cwd: this.parser.cwd
        });
    }
    async runAsync() {
        const terminal = new terminal_1.Terminal(new terminal_1.ConsoleTerminalProvider());
        const selection = await this._selectionParameters.getSelectedProjectsAsync(terminal);
        node_core_library_1.Sort.sortSetBy(selection, (x) => x.packageName);
        if (this._jsonFlag.value && this._detailedFlag.value) {
            throw new Error(`The parameters "--json" and "--detailed" cannot be used together.`);
        }
        if (this._jsonFlag.value) {
            this._printJson(selection);
        }
        else if (this._version.value || this._path.value || this._fullPath.value || this._detailedFlag.value) {
            await this._printListTableAsync(selection);
        }
        else {
            this._printList(selection);
        }
    }
    _printJson(selection) {
        const projects = Array.from(selection, (config) => {
            let reviewCategory;
            let shouldPublish;
            let versionPolicy;
            let versionPolicyName;
            let subspaceName;
            if (config.versionPolicy !== undefined) {
                const definitionName = VersionPolicy_1.VersionPolicyDefinitionName[config.versionPolicy.definitionName];
                versionPolicy = `${definitionName}`;
                versionPolicyName = config.versionPolicy.policyName;
            }
            else {
                shouldPublish = config.shouldPublish;
            }
            if (config.reviewCategory) {
                reviewCategory = config.reviewCategory;
            }
            if (this.rushConfiguration.subspacesFeatureEnabled) {
                subspaceName = config.subspace.subspaceName;
            }
            return {
                name: config.packageName,
                version: config.packageJson.version,
                path: config.projectRelativeFolder,
                fullPath: config.projectFolder,
                versionPolicy,
                versionPolicyName,
                shouldPublish,
                reviewCategory,
                tags: Array.from(config.tags),
                subspaceName
            };
        });
        const output = {
            projects
        };
        // eslint-disable-next-line no-console
        console.log(JSON.stringify(output, undefined, 2));
    }
    _printList(selection) {
        for (const project of selection) {
            // eslint-disable-next-line no-console
            console.log(project.packageName);
        }
    }
    async _printListTableAsync(selection) {
        const tableHeader = ['Project'];
        if (this.rushConfiguration.subspacesFeatureEnabled) {
            tableHeader.push('Subspace');
        }
        if (this._version.value || this._detailedFlag.value) {
            tableHeader.push('Version');
        }
        if (this._path.value || this._detailedFlag.value) {
            tableHeader.push('Path');
        }
        if (this._fullPath.value) {
            tableHeader.push('Full Path');
        }
        if (this._detailedFlag.value) {
            tableHeader.push('Version policy');
            tableHeader.push('Version policy name');
            tableHeader.push('Should publish');
            tableHeader.push('Review category');
            tableHeader.push('Tags');
        }
        const { default: CliTable } = await Promise.resolve().then(() => __importStar(require('cli-table')));
        const table = new CliTable({
            head: tableHeader
        });
        for (const project of selection) {
            const packageRow = [];
            function appendToPackageRow(value) {
                packageRow.push(value === undefined ? 'UNDEFINED' : value);
            }
            appendToPackageRow(project.packageName);
            if (this.rushConfiguration.subspacesFeatureEnabled) {
                appendToPackageRow(project.subspace.subspaceName);
            }
            if (this._version.value || this._detailedFlag.value) {
                appendToPackageRow(project.packageJson.version);
            }
            if (this._path.value || this._detailedFlag.value) {
                appendToPackageRow(project.projectRelativeFolder);
            }
            if (this._fullPath.value) {
                appendToPackageRow(project.projectFolder);
            }
            if (this._detailedFlag.value) {
                // When we HAVE a version policy
                let versionPolicyDefinitionName = '';
                let versionPolicyName = '';
                // When we DO NOT have version policy, fallback to shouldPublish boolean
                let shouldPublish = '';
                let reviewCategory = '';
                if (project.versionPolicy !== undefined) {
                    const definitionName = VersionPolicy_1.VersionPolicyDefinitionName[project.versionPolicy.definitionName];
                    versionPolicyDefinitionName = definitionName;
                    versionPolicyName = project.versionPolicy.policyName;
                }
                else {
                    shouldPublish = `${project.shouldPublish}`;
                }
                if (project.reviewCategory) {
                    reviewCategory = project.reviewCategory;
                }
                appendToPackageRow(versionPolicyDefinitionName);
                appendToPackageRow(versionPolicyName);
                appendToPackageRow(shouldPublish);
                appendToPackageRow(reviewCategory);
                appendToPackageRow(Array.from(project.tags).join(', '));
            }
            table.push(packageRow);
        }
        // eslint-disable-next-line no-console
        console.log(table.toString());
    }
}
exports.ListAction = ListAction;
//# sourceMappingURL=ListAction.js.map