"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 loadJsonFile = require("load-json-file");
const path = require("path");
const rimraf = require("rimraf-then");
const supi_1 = require("supi");
const createStoreController_1 = require("../createStoreController");
function installCmd(input, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        // Removing existing pnpm lockfile
        // it should not influence the new one
        yield rimraf(path.join(opts.prefix, 'shrinkwrap.yaml'));
        const npmPackageLock = yield readNpmLockfile(opts.prefix);
        const versionsByPackageNames = {};
        getAllVersionsByPackageNames(npmPackageLock, versionsByPackageNames);
        const preferredVersions = getPreferredVersions(versionsByPackageNames);
        const store = yield createStoreController_1.default(opts);
        const installOpts = Object.assign({}, opts, { preferredVersions, shrinkwrapOnly: true, store: store.path, storeController: store.ctrl });
        yield supi_1.install(installOpts);
    });
}
exports.default = installCmd;
function readNpmLockfile(prefix) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            return yield loadJsonFile(path.join(prefix, 'package-lock.json'));
        }
        catch (err) {
            if (err['code'] !== 'ENOENT')
                throw err; // tslint:disable-line:no-string-literal
        }
        try {
            return yield loadJsonFile(path.join(prefix, 'npm-shrinkwrap.json'));
        }
        catch (err) {
            if (err['code'] !== 'ENOENT')
                throw err; // tslint:disable-line:no-string-literal
        }
        const err = new Error('No package-lock.json or npm-shrinkwrap.json found');
        err['code'] = 'ERR_PNPM_NPM_LOCKFILE_NOT_FOUND'; // tslint:disable-line:no-string-literal
        throw err;
    });
}
function getPreferredVersions(versionsByPackageNames) {
    const preferredVersions = {};
    for (const packageName of Object.keys(versionsByPackageNames)) {
        if (versionsByPackageNames[packageName].size === 1) {
            preferredVersions[packageName] = {
                selector: Array.from(versionsByPackageNames[packageName])[0],
                type: 'version',
            };
        }
        else {
            preferredVersions[packageName] = {
                selector: Array.from(versionsByPackageNames[packageName]).join(' || '),
                type: 'range',
            };
        }
    }
    return preferredVersions;
}
function getAllVersionsByPackageNames(npmPackageLock, versionsByPackageNames) {
    if (!npmPackageLock.dependencies)
        return;
    for (const packageName of Object.keys(npmPackageLock.dependencies)) {
        if (!versionsByPackageNames[packageName]) {
            versionsByPackageNames[packageName] = new Set();
        }
        versionsByPackageNames[packageName].add(npmPackageLock.dependencies[packageName].version);
    }
    for (const packageName of Object.keys(npmPackageLock.dependencies)) {
        getAllVersionsByPackageNames(npmPackageLock.dependencies[packageName], versionsByPackageNames);
    }
}
//# sourceMappingURL=import.js.map