"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const getContext_1 = require("./getContext");
const getSaveType_1 = require("../getSaveType");
const removeDeps_1 = require("../removeDeps");
const extendOptions_1 = require("./extendOptions");
const lock_1 = require("./lock");
const pnpm_lockfile_1 = require("pnpm-lockfile");
const modulesController_1 = require("../fs/modulesController");
const removeOrphanPkgs_1 = require("./removeOrphanPkgs");
const pnpmPkgJson_1 = require("../pnpmPkgJson");
const safeIsInnerLink_1 = require("../safeIsInnerLink");
const removeTopDependency_1 = require("../removeTopDependency");
function uninstallCmd(pkgsToUninstall, maybeOpts) {
    return __awaiter(this, void 0, void 0, function* () {
        const opts = extendOptions_1.default(maybeOpts);
        return lock_1.default(opts.prefix, () => __awaiter(this, void 0, void 0, function* () {
            const ctx = yield getContext_1.default(opts);
            if (!ctx.pkg) {
                throw new Error('No package.json found - cannot uninstall');
            }
            const pkg = ctx.pkg;
            if (opts.lock === false) {
                return run();
            }
            return lock_1.default(ctx.storePath, run, { stale: opts.lockStaleDuration });
            function run() {
                return uninstallInContext(pkgsToUninstall, pkg, ctx, opts);
            }
        }), { stale: opts.lockStaleDuration });
    });
}
exports.default = uninstallCmd;
function uninstallInContext(pkgsToUninstall, pkg, ctx, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        const saveType = getSaveType_1.default(opts);
        if (saveType) {
            const pkgJsonPath = path.join(ctx.root, 'package.json');
            const pkg = yield removeDeps_1.default(pkgJsonPath, pkgsToUninstall, saveType);
            for (let depName in ctx.shrinkwrap.dependencies) {
                if (!isDependentOn(pkg, depName)) {
                    delete ctx.shrinkwrap.dependencies[depName];
                    delete ctx.shrinkwrap.specifiers[depName];
                }
            }
            const newShr = yield pnpm_lockfile_1.prune(ctx.shrinkwrap, pkg);
            const removedPkgIds = yield removeOrphanPkgs_1.default(ctx.privateShrinkwrap, newShr, ctx.root, ctx.storePath);
            yield pnpm_lockfile_1.save(ctx.root, newShr);
            yield modulesController_1.save(path.join(ctx.root, 'node_modules'), {
                packageManager: `${pnpmPkgJson_1.default.name}@${pnpmPkgJson_1.default.version}`,
                storePath: ctx.storePath,
                skipped: Array.from(ctx.skipped).filter(pkgId => removedPkgIds.indexOf(pkgId) === -1),
            });
            yield removeOuterLinks(pkgsToUninstall, path.join(ctx.root, 'node_modules'));
        }
    });
}
exports.uninstallInContext = uninstallInContext;
function isDependentOn(pkg, depName) {
    return [
        'dependencies',
        'devDependencies',
        'optionalDependencies',
    ]
        .some(deptype => pkg[deptype] && pkg[deptype][depName]);
}
function removeOuterLinks(pkgsToUninstall, modules) {
    return __awaiter(this, void 0, void 0, function* () {
        for (const pkgToUninstall of pkgsToUninstall) {
            if (!(yield safeIsInnerLink_1.default(modules, pkgToUninstall))) {
                yield removeTopDependency_1.default(pkgToUninstall, modules);
            }
        }
    });
}
//# sourceMappingURL=uninstall.js.map