"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 fs = require("mz/fs");
const lifecycle = require("npm-lifecycle");
const path = require("path");
const readPkg_1 = require("../fs/readPkg");
const loggers_1 = require("../loggers");
function noop() { } // tslint:disable-line:no-empty
function postInstall(root, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        const pkg = yield readPkg_1.fromDir(root);
        const scripts = pkg && pkg.scripts || {};
        if (!scripts['install']) {
            yield checkBindingGyp(root, scripts);
        }
        const modulesDir = path.join(opts.initialWD, 'node_modules');
        const scriptsOpts = {
            modulesDir,
            pkgId: opts.pkgId,
            rawNpmConfig: opts.rawNpmConfig,
            root,
            unsafePerm: opts.unsafePerm,
        };
        yield npmRunScript('preinstall', pkg, scriptsOpts);
        yield npmRunScript('install', pkg, scriptsOpts);
        yield npmRunScript('postinstall', pkg, scriptsOpts);
        return !!scripts['preinstall'] || !!scripts['install'] || !!scripts['postinstall']; // tslint:disable-line:no-string-literal
    });
}
exports.default = postInstall;
function npmRunScript(stage, pkg, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        if (!pkg.scripts || !pkg.scripts[stage])
            return;
        return lifecycle(pkg, stage, opts.root, {
            config: opts.rawNpmConfig,
            dir: opts.modulesDir,
            log: {
                clearProgress: noop,
                info: noop,
                level: opts.stdio === 'inherit' ? undefined : 'silent',
                pause: noop,
                resume: noop,
                showProgress: noop,
                silly: npmLog,
                verbose: npmLog,
                warn: noop,
            },
            stdio: opts.stdio || 'pipe',
            unsafePerm: opts.unsafePerm,
        });
        function npmLog(prefix, logid, stdtype, line) {
            switch (stdtype) {
                case 'stdout':
                    loggers_1.lifecycleLogger.info({
                        line: line.toString(),
                        pkgId: opts.pkgId,
                        script: stage,
                    });
                    return;
                case 'stderr':
                    loggers_1.lifecycleLogger.error({
                        line: line.toString(),
                        pkgId: opts.pkgId,
                        script: stage,
                    });
                    return;
                case 'Returned: code:':
                    if (opts.stdio === 'inherit') {
                        // Preventing the pnpm reporter from overriding the project's script output
                        return;
                    }
                    const code = arguments[3];
                    loggers_1.lifecycleLogger[code === 0 ? 'info' : 'error']({
                        exitCode: code,
                        pkgId: opts.pkgId,
                        script: stage,
                    });
                    return;
            }
        }
    });
}
exports.npmRunScript = npmRunScript;
/**
 * Run node-gyp when binding.gyp is available. Only do this when there's no
 * `install` script (see `npm help scripts`).
 */
function checkBindingGyp(root, scripts) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            yield fs.stat(path.join(root, 'binding.gyp'));
            // if fs.stat didn't throw, it means that binding.gyp exists: the default install script is:
            scripts['install'] = 'node-gyp rebuild'; // tslint:disable-line:no-string-literal
        }
        catch (_a) { } // tslint:disable-line:no-empty
    });
}
//# sourceMappingURL=postInstall.js.map