"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const error_1 = require("@pnpm/error");
const lifecycle_1 = require("@pnpm/lifecycle");
const utils_1 = require("@pnpm/utils");
const R = require("ramda");
const readImporterManifest_1 = require("../readImporterManifest");
async function run(args, opts) {
    const prefix = opts.localPrefix;
    const manifest = await readImporterManifest_1.readImporterManifestOnly(prefix, opts);
    const scriptName = args[0];
    if (!scriptName) {
        printProjectCommands(manifest);
        return;
    }
    if (scriptName !== 'start' && (!manifest.scripts || !manifest.scripts[scriptName])) {
        throw new error_1.default('NO_SCRIPT', `Missing script: ${scriptName}`);
    }
    const lifecycleOpts = {
        args: args.slice(1),
        depPath: prefix,
        extraBinPaths: opts.extraBinPaths,
        pkgRoot: prefix,
        rawNpmConfig: opts.rawNpmConfig,
        rootNodeModulesDir: await utils_1.realNodeModulesDir(prefix),
        stdio: 'inherit',
        unsafePerm: true,
    };
    if (manifest.scripts && manifest.scripts[`pre${scriptName}`]) {
        await lifecycle_1.default(`pre${scriptName}`, manifest, lifecycleOpts);
    }
    await lifecycle_1.default(scriptName, manifest, lifecycleOpts);
    if (manifest.scripts && manifest.scripts[`post${scriptName}`]) {
        await lifecycle_1.default(`post${scriptName}`, manifest, lifecycleOpts);
    }
}
exports.default = run;
const ALL_LIFECYCLE_SCRIPTS = new Set([
    'prepublish',
    'prepare',
    'prepublishOnly',
    'prepack',
    'postpack',
    'publish',
    'postpublish',
    'preinstall',
    'install',
    'postinstall',
    'preuninstall',
    'uninstall',
    'postuninstall',
    'preversion',
    'version',
    'postversion',
    'pretest',
    'test',
    'posttest',
    'prestop',
    'stop',
    'poststop',
    'prestart',
    'start',
    'poststart',
    'prerestart',
    'restart',
    'postrestart',
    'preshrinkwrap',
    'shrinkwrap',
    'postshrinkwrap',
]);
function printProjectCommands(manifest) {
    const lifecycleScripts = [];
    const otherScripts = [];
    for (const [scriptName, script] of R.toPairs(manifest.scripts || {})) {
        if (ALL_LIFECYCLE_SCRIPTS.has(scriptName)) {
            lifecycleScripts.push([scriptName, script]);
        }
        else {
            otherScripts.push([scriptName, script]);
        }
    }
    if (lifecycleScripts.length === 0 && otherScripts.length === 0) {
        console.log(`There are no scripts specified.`);
        return;
    }
    let output = '';
    if (lifecycleScripts.length > 0) {
        output += `Lifecycle scripts:\n${renderCommands(lifecycleScripts)}`;
    }
    if (otherScripts.length > 0) {
        if (output !== '')
            output += '\n\n';
        output += `Commands available via "pnpm run":\n${renderCommands(otherScripts)}`;
    }
    console.log(output);
}
function renderCommands(commands) {
    return commands.map(([scriptName, script]) => `  ${scriptName}\n    ${script}`).join('\n');
}
async function start(args, opts) {
    return run(['start', ...args], opts);
}
exports.start = start;
async function stop(args, opts) {
    return run(['stop', ...args], opts);
}
exports.stop = stop;
async function test(args, opts) {
    return run(['test', ...args], opts);
}
exports.test = test;
async function restart(args, opts) {
    await stop(args, opts);
    await run(['restart', ...args], opts);
    await start(args, opts);
}
exports.restart = restart;
