"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const error_1 = require("@pnpm/error");
const logger_1 = require("@pnpm/logger");
const chalk = require("chalk");
const fs = require("fs");
class BadReadPackageHookError extends error_1.default {
    constructor(pnpmfile, message) {
        super('BAD_READ_PACKAGE_HOOK_RESULT', `${message} Hook imported via ${pnpmfile}`);
        this.pnpmfile = pnpmfile;
    }
}
class PnpmFileFailError extends error_1.default {
    constructor(pnpmfile, originalError) {
        super('PNPMFILE_FAIL', `Error during pnpmfile execution. pnpmfile: "${pnpmfile}". Error: "${originalError.message}".`);
        this.pnpmfile = pnpmfile;
        this.originalError = originalError;
    }
}
exports.default = (pnpmFilePath, prefix) => {
    var _a, _b;
    try {
        const pnpmfile = require(pnpmFilePath);
        logger_1.default.info({
            message: `Using hooks from: ${pnpmFilePath}`,
            prefix,
        });
        if (typeof pnpmfile === 'undefined') {
            logger_1.default.warn({
                message: `Ignoring the pnpmfile at "${pnpmFilePath}". It exports "undefined".`,
                prefix,
            });
            return undefined;
        }
        if (((_a = pnpmfile === null || pnpmfile === void 0 ? void 0 : pnpmfile.hooks) === null || _a === void 0 ? void 0 : _a.readPackage) && typeof pnpmfile.hooks.readPackage !== 'function') {
            throw new TypeError('hooks.readPackage should be a function');
        }
        if ((_b = pnpmfile === null || pnpmfile === void 0 ? void 0 : pnpmfile.hooks) === null || _b === void 0 ? void 0 : _b.readPackage) {
            const readPackage = pnpmfile.hooks.readPackage;
            pnpmfile.hooks.readPackage = function (pkg, ...args) {
                pkg.dependencies = pkg.dependencies || {};
                pkg.devDependencies = pkg.devDependencies || {};
                pkg.optionalDependencies = pkg.optionalDependencies || {};
                pkg.peerDependencies = pkg.peerDependencies || {};
                const newPkg = readPackage(pkg, ...args);
                if (!newPkg) {
                    throw new BadReadPackageHookError(pnpmFilePath, 'readPackage hook did not return a package manifest object.');
                }
                const dependencies = ['dependencies', 'optionalDependencies', 'peerDependencies'];
                for (let dep of dependencies) {
                    if (newPkg[dep] && typeof newPkg[dep] !== 'object') {
                        throw new BadReadPackageHookError(pnpmFilePath, `readPackage hook returned package manifest object's property '${dep}' must be an object.`);
                    }
                }
                return newPkg;
            };
        }
        pnpmfile.filename = pnpmFilePath;
        return pnpmfile;
    }
    catch (err) {
        if (err instanceof SyntaxError) {
            console.error(chalk.red('A syntax error in the pnpmfile.js\n'));
            console.error(err);
            process.exit(1);
            return;
        }
        if (err.code !== 'MODULE_NOT_FOUND' || pnpmFileExistsSync(pnpmFilePath)) {
            throw new PnpmFileFailError(pnpmFilePath, err);
        }
        return undefined;
    }
};
function pnpmFileExistsSync(pnpmFilePath) {
    const pnpmFileRealName = pnpmFilePath.endsWith('.js')
        ? pnpmFilePath
        : `${pnpmFilePath}.js`;
    return fs.existsSync(pnpmFileRealName);
}
