"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chalk_1 = require("chalk");
const commonTags = require("common-tags");
const R = require("ramda");
const StackTracey = require("stacktracey");
const constants_1 = require("./constants");
const stripIndent = commonTags.stripIndent;
const stripIndents = commonTags.stripIndents;
const highlight = chalk_1.default.yellow;
const colorPath = chalk_1.default.gray;
function reportError(logObj) {
    if (logObj['err']) {
        const err = logObj['err'];
        switch (err.code) {
            case 'UNEXPECTED_STORE':
                return reportUnexpectedStore(err, logObj['message']);
            case 'STORE_BREAKING_CHANGE':
                return reportStoreBreakingChange(err, logObj['message']);
            case 'MODULES_BREAKING_CHANGE':
                return reportModulesBreakingChange(err, logObj['message']);
            case 'MODIFIED_DEPENDENCY':
                return reportModifiedDependency(err, logObj['message']);
            case 'SHRINKWRAP_BREAKING_CHANGE':
                return reportShrinkwrapBreakingChange(err, logObj['message']);
            case 'RECURSIVE_RUN_NO_SCRIPT':
                return formatErrorSummary(err.message);
            case 'ERR_PNPM_NO_MATCHING_VERSION':
                return formatNoMatchingVersion(err, logObj['message']);
            default:
                // Errors with known error codes are printed w/o stack trace
                if (err.code && err.code.startsWith && err.code.startsWith('ERR_PNPM_')) {
                    return formatErrorSummary(err.message);
                }
                return formatGenericError(err.message || logObj['message'], err.stack);
        }
    }
    return formatErrorSummary(logObj['message']);
}
exports.default = reportError;
function formatNoMatchingVersion(err, msg) {
    const meta = msg['packageMeta'];
    let output = stripIndent `
    ${formatErrorSummary(err.message)}

    The latest release of ${meta.name} is "${meta['dist-tags'].latest}".
  ` + constants_1.EOL;
    if (!R.equals(R.keys(meta['dist-tags']), ['latest'])) {
        output += constants_1.EOL + 'Other releases are:' + constants_1.EOL;
        for (const tag in meta['dist-tags']) {
            if (tag !== 'latest') {
                output += `  * ${tag}: ${meta['dist-tags'][tag]}${constants_1.EOL}`;
            }
        }
    }
    output += `${constants_1.EOL}If you need the full list of all ${Object.keys(meta.versions).length} published versions run "$ pnpm view ${meta.name} versions".`;
    return output;
}
function reportUnexpectedStore(err, msg) {
    return stripIndent `
    ${formatErrorSummary(err.message)}

    expected: ${highlight(msg['expectedStorePath'])}
    actual: ${highlight(msg['actualStorePath'])}

    If you want to use the new store, run the same command with the ${highlight('--force')} parameter.
  `;
}
function reportStoreBreakingChange(err, msg) {
    let output = stripIndent `
    ${formatErrorSummary(`The store used for the current node_modules is incomatible with the current version of pnpm`)}
    Store path: ${colorPath(msg['storePath'])}

    Try running the same command with the ${highlight('--force')} parameter.
  `;
    if (msg['additionalInformation']) {
        output += constants_1.EOL + constants_1.EOL + msg['additionalInformation'];
    }
    output += formatRelatedSources(msg);
    return output;
}
function reportModulesBreakingChange(err, msg) {
    let output = stripIndent `
    ${formatErrorSummary(`The current version of pnpm is not compatible with the available node_modules structure`)}
    node_modules path: ${colorPath(msg['modulesPath'])}

    Run ${highlight('pnpm install --force')} to recreate node_modules.
  `;
    if (msg['additionalInformation']) {
        output += constants_1.EOL + constants_1.EOL + msg['additionalInformation'];
    }
    output += formatRelatedSources(msg);
    return output;
}
function formatRelatedSources(msg) {
    let output = '';
    if (!msg['relatedIssue'] && !msg['relatedPR'])
        return output;
    output += constants_1.EOL;
    if (msg['relatedIssue']) {
        output += constants_1.EOL + `Related issue: ${colorPath(`https://github.com/pnpm/pnpm/issues/${msg['relatedIssue']}`)}`;
    }
    if (msg['relatedPR']) {
        output += constants_1.EOL + `Related PR: ${colorPath(`https://github.com/pnpm/pnpm/pull/${msg['relatedPR']}`)}`;
    }
    return output;
}
function formatGenericError(errorMessage, stack) {
    if (stack) {
        let prettyStack;
        try {
            prettyStack = new StackTracey(stack).pretty;
        }
        catch (err) {
            prettyStack = undefined;
        }
        if (prettyStack) {
            return stripIndents `
          ${formatErrorSummary(errorMessage)}
          ${prettyStack}
        `;
        }
    }
    return formatErrorSummary(errorMessage);
}
function formatErrorSummary(message) {
    return `${chalk_1.default.bgRed.black('\u2009ERROR\u2009')} ${chalk_1.default.red(message)}`;
}
function reportModifiedDependency(err, msg) {
    return stripIndent `
    ${formatErrorSummary('Packages in the store have been mutated')}

    These packages are modified:
    ${msg['modified'].map((pkgPath) => colorPath(pkgPath)).join(constants_1.EOL)}

    You can run ${highlight('pnpm install')} to refetch the modified packages
  `;
}
function reportShrinkwrapBreakingChange(err, msg) {
    return stripIndent `
    ${formatErrorSummary(err.message)}

    Run with the ${highlight('--force')} parameter to recreate the shrinkwrap file.
  `;
}
//# sourceMappingURL=reportError.js.map