/* jscpd:ignore-start */
import { SfCommand, Flags, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
import axios from 'axios';
import c from 'chalk';
import fs from 'fs-extra';
import * as path from 'path';
// import * as packages from '../../../../defaults/packages.json'
import { MetadataUtils } from '../../../common/metadata-utils/index.js';
import { isCI, uxLog } from '../../../common/utils/index.js';
import { managePackageConfig } from '../../../common/utils/orgUtils.js';
import { prompts } from '../../../common/utils/prompts.js';
import { PACKAGE_ROOT_DIR } from '../../../settings.js';
import { WebSocketClient } from '../../../common/websocketClient.js';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('sfdx-hardis', 'org');
export default class PackageVersionInstall extends SfCommand {
    static title = 'Install packages in an org';
    static description = `Install a package in an org using its id (starting with **04t**)

Assisted menu to propose to update \`installedPackages\` property in \`.sfdx-hardis.yml\`
`;
    static examples = ['$ sf hardis:package:install'];
    // public static args = [{name: 'file'}];
    static flags = {
        package: Flags.string({
            char: 'p',
            description: 'Package Version Id to install (04t...)',
        }),
        debug: Flags.boolean({
            char: 'd',
            default: false,
            description: messages.getMessage('debugMode'),
        }),
        websocket: Flags.string({
            description: messages.getMessage('websocket'),
        }),
        installationkey: Flags.string({
            char: 'k',
            default: '',
            description: messages.getMessage('packageInstallationKey'),
        }),
        skipauth: Flags.boolean({
            description: 'Skip authentication check when a default username is required',
        }),
        'target-org': requiredOrgFlagWithDeprecations,
    };
    /* jscpd:ignore-end */
    allPackagesFileName = path.join(PACKAGE_ROOT_DIR, 'defaults/packages.json');
    sfdxProjectJsonFileName = path.join(process.cwd(), 'sfdx-project.json');
    async run() {
        const { flags } = await this.parse(PackageVersionInstall);
        const packagesRaw = await fs.readFile(this.allPackagesFileName, 'utf8');
        const packages = JSON.parse(packagesRaw);
        const packageId = flags.package || null;
        const packagesToInstall = [];
        // If no package Id is sent, ask user what package he/she wants to install
        if (!isCI && (packageId == null || !packageId.startsWith('04t'))) {
            const allPackages = packages.map((pack) => ({
                title: `${c.yellow(pack.name)} - ${pack.repoUrl || 'Bundle'}`,
                value: pack,
            }));
            allPackages.push({ title: 'Other', value: 'other' });
            const packageResponse = await prompts({
                type: 'select',
                name: 'value',
                message: c.cyanBright(`Please select the package you want to install on org  ${c.green(flags['target-org'].getUsername())}`),
                description: 'Choose which package to install from the available list',
                placeholder: 'Select a package',
                choices: allPackages,
                initial: 0,
            });
            if (packageResponse.value === 'other') {
                const packageDtlResponse = await prompts([
                    {
                        type: 'text',
                        name: 'value',
                        message: c.cyanBright('What is the id of the Package Version to install ? (starting with 04t)\nYou can find it using tooling api request ' +
                            c.bold('Select Id,SubscriberPackage.Name,SubscriberPackageVersionId from InstalledSubscriberPackage')),
                        description: 'Enter the package version ID for the package you want to install',
                        placeholder: 'Ex: 04t2p000000XXXXXX',
                    },
                    {
                        type: 'text',
                        name: 'installationkey',
                        message: c.cyanBright('Enter the password for this package (leave empty if package is not protected by a password)'),
                        description: 'Provide the installation password if the package is protected',
                        placeholder: 'Ex: mypassword123',
                    },
                ]);
                const pckg = {
                    SubscriberPackageVersionId: packageDtlResponse.value,
                };
                if (packageDtlResponse.installationkey) {
                    pckg.installationkey = packageDtlResponse.installationkey;
                }
                packagesToInstall.push(pckg);
            }
            else if (packageResponse.value.bundle) {
                // Package bundle selected
                const packagesToAdd = packageResponse.value.packages.map((packageId) => {
                    return packages.filter((pckg) => pckg.package === packageId)[0];
                });
                packagesToInstall.push(...packagesToAdd);
            }
            else {
                // Single package selected
                packagesToInstall.push(packageResponse.value.package);
            }
        }
        else {
            const pckg = {
                SubscriberPackageVersionId: packageId || '',
            };
            if (flags.installationkey) {
                pckg.installationkey = flags.installationkey;
            }
            packagesToInstall.push(pckg);
        }
        // Complete packages with remote information
        const packagesToInstallCompleted = await Promise.all(packagesToInstall.map(async (pckg) => {
            if (pckg.SubscriberPackageVersionId == null) {
                const configResp = await axios.get(pckg.configUrl);
                const packageAliases = configResp.data.packageAliases || [];
                pckg.SubscriberPackageName = pckg.package;
                if (pckg.package.includes('@')) {
                    pckg.SubscriberPackageVersionId = packageAliases[pckg.package];
                }
                else {
                    // use last occurrence of package alias
                    for (const packageAlias of Object.keys(packageAliases)) {
                        if (packageAlias.startsWith(pckg.package)) {
                            pckg.SubscriberPackageName = packageAlias;
                            pckg.SubscriberPackageVersionId = packageAliases[packageAlias];
                        }
                    }
                }
            }
            return pckg;
        }));
        // Install packages
        await MetadataUtils.installPackagesOnOrg(packagesToInstallCompleted, null, this, 'install');
        const installedPackages = await MetadataUtils.listInstalledPackages(null, this);
        uxLog("other", this, c.italic(c.grey('New package list on org:\n' + JSON.stringify(installedPackages, null, 2))));
        if (!isCI) {
            // Manage package install config storage
            await managePackageConfig(installedPackages, packagesToInstallCompleted);
        }
        WebSocketClient.sendRefreshPipelineMessage();
        // Return an object to be displayed with --json
        return { outputString: 'Installed package(s)' };
    }
}
//# sourceMappingURL=install.js.map