// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
import * as path from 'node:path';
import { FileSystem, JsonFile, PosixModeBits } from '@rushstack/node-core-library';
import { Autoinstaller } from '../../logic/Autoinstaller';
import { RushConstants } from '../../logic/RushConstants';
import { PluginLoaderBase } from './PluginLoaderBase';
/**
 * @beta
 */
export class AutoinstallerPluginLoader extends PluginLoaderBase {
    constructor(options) {
        super(options);
        this.autoinstaller = new Autoinstaller({
            autoinstallerName: options.pluginConfiguration.autoinstallerName,
            rushConfiguration: this._rushConfiguration,
            restrictConsoleOutput: options.restrictConsoleOutput,
            rushGlobalFolder: options.rushGlobalFolder
        });
        this.packageFolder = path.join(this.autoinstaller.folderFullPath, 'node_modules', this.packageName);
    }
    /**
     * The folder where rush plugins static files are stored.
     * Example: `C:\MyRepo\common\autoinstallers\<autoinstaller_name>\rush-plugins`
     */
    static getPluginAutoinstallerStorePath(autoinstaller) {
        return path.join(autoinstaller.folderFullPath, 'rush-plugins');
    }
    update() {
        const packageName = this.packageName;
        const pluginName = this.pluginName;
        const packageFolder = this.packageFolder;
        const manifestPath = path.join(packageFolder, RushConstants.rushPluginManifestFilename);
        // validate
        const manifest = JsonFile.loadAndValidate(manifestPath, AutoinstallerPluginLoader._jsonSchema);
        const destinationManifestPath = this._getManifestPath();
        FileSystem.copyFile({
            sourcePath: manifestPath,
            destinationPath: destinationManifestPath
        });
        // Make permission consistent since it will be committed to Git
        FileSystem.changePosixModeBits(destinationManifestPath, 
        // eslint-disable-next-line no-bitwise
        PosixModeBits.AllRead | PosixModeBits.UserWrite);
        const pluginManifest = manifest.plugins.find((item) => item.pluginName === pluginName);
        if (!pluginManifest) {
            throw new Error(`A plugin named "${pluginName}" is not provided by the Rush plugin package "${packageName}"`);
        }
        const commandLineJsonFilePath = pluginManifest.commandLineJsonFilePath;
        if (commandLineJsonFilePath) {
            const commandLineJsonFullFilePath = path.join(packageFolder, commandLineJsonFilePath);
            if (!FileSystem.exists(commandLineJsonFullFilePath)) {
                this._terminal.writeErrorLine(`The Rush plugin "${pluginName}" from "${packageName}" specifies a commandLineJsonFilePath` +
                    ` ${commandLineJsonFilePath} that does not exist.`);
            }
            const destinationCommandLineJsonFilePath = this._getCommandLineJsonFilePath();
            FileSystem.copyFile({
                sourcePath: commandLineJsonFullFilePath,
                destinationPath: destinationCommandLineJsonFilePath
            });
            // Make permission consistent since it will be committed to Git
            FileSystem.changePosixModeBits(destinationCommandLineJsonFilePath, 
            // eslint-disable-next-line no-bitwise
            PosixModeBits.AllRead | PosixModeBits.UserWrite);
        }
    }
    _getCommandLineAdditionalPathFolders() {
        const additionalPathFolders = super._getCommandLineAdditionalPathFolders();
        additionalPathFolders.push(
        // Example: `common/autoinstaller/plugins/node_modules/.bin`
        path.join(this.autoinstaller.folderFullPath, 'node_modules', '.bin'));
        return additionalPathFolders;
    }
    _getPluginOptions() {
        const optionsJsonFilePath = this._getPluginOptionsJsonFilePath();
        const optionsSchema = this._getRushPluginOptionsSchema();
        let pluginOptions = {};
        try {
            pluginOptions = JsonFile.load(optionsJsonFilePath);
        }
        catch (e) {
            if (FileSystem.isFileDoesNotExistError(e)) {
                if (optionsSchema) {
                    throw new Error(`Plugin options are required by ${this.pluginName} from package ${this.packageName}, please create it at ${optionsJsonFilePath}.`);
                }
                else {
                    return {};
                }
            }
            throw e;
        }
        if (optionsSchema) {
            optionsSchema.validateObject(pluginOptions, optionsJsonFilePath);
        }
        return pluginOptions;
    }
    _getManifestPath() {
        return path.join(AutoinstallerPluginLoader.getPluginAutoinstallerStorePath(this.autoinstaller), this.packageName, RushConstants.rushPluginManifestFilename);
    }
    _getCommandLineJsonFilePath() {
        return path.join(AutoinstallerPluginLoader.getPluginAutoinstallerStorePath(this.autoinstaller), this.packageName, this.pluginName, RushConstants.commandLineFilename);
    }
}
//# sourceMappingURL=AutoinstallerPluginLoader.js.map