"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 rimraf = require("rimraf-then");
const path = require("path");
const shrinkwrap_1 = require("../fs/shrinkwrap");
const storeController_1 = require("../fs/storeController");
const R = require("ramda");
const npa = require("npm-package-arg");
const removeTopDependency_1 = require("../removeTopDependency");
function removeOrphanPkgs(oldShr, newShr, root, storePath) {
    return __awaiter(this, void 0, void 0, function* () {
        const oldPkgNames = Object.keys(oldShr.dependencies).map(rawSpec => npa(rawSpec)).map((spec) => spec.name);
        const newPkgNames = Object.keys(newShr.dependencies).map(rawSpec => npa(rawSpec)).map((spec) => spec.name);
        const removedTopDeps = R.difference(oldPkgNames, newPkgNames);
        const rootModules = path.join(root, 'node_modules');
        yield Promise.all(removedTopDeps.map(depName => removeTopDependency_1.default(depName, rootModules)));
        const oldPkgIds = Object.keys(oldShr.packages).map(shortId => shrinkwrap_1.shortIdToFullId(shortId, oldShr.registry));
        const newPkgIds = Object.keys(newShr.packages).map(shortId => shrinkwrap_1.shortIdToFullId(shortId, newShr.registry));
        const store = (yield storeController_1.read(storePath)) || {};
        const notDependents = R.difference(oldPkgIds, newPkgIds);
        yield Promise.all(Array.from(notDependents).map((notDependent) => __awaiter(this, void 0, void 0, function* () {
            if (store[notDependent]) {
                store[notDependent].splice(store[notDependent].indexOf(root), 1);
                if (!store[notDependent].length) {
                    delete store[notDependent];
                    yield rimraf(path.join(storePath, notDependent));
                }
            }
            yield rimraf(path.join(rootModules, `.${notDependent}`));
        })));
        const newDependents = R.difference(newPkgIds, oldPkgIds);
        newDependents.forEach(newDependent => {
            store[newDependent] = store[newDependent] || [];
            if (store[newDependent].indexOf(root) === -1) {
                store[newDependent].push(root);
            }
        });
        yield storeController_1.save(storePath, store);
        return notDependents;
    });
}
exports.default = removeOrphanPkgs;
//# sourceMappingURL=removeOrphanPkgs.js.map