"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateReconfigureBranch = exports.getReconfigureBranchName = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const json5_1 = tslib_1.__importDefault(require("json5"));
const validation_1 = require("../../../config/validation");
const logger_1 = require("../../../logger");
const platform_1 = require("../../../modules/platform");
const comment_1 = require("../../../modules/platform/comment");
const scm_1 = require("../../../modules/platform/scm");
const repository_1 = require("../../../util/cache/repository");
const fs_1 = require("../../../util/fs");
const git_1 = require("../../../util/git");
const regex_1 = require("../../../util/regex");
const merge_1 = require("../init/merge");
const reconfigure_cache_1 = require("./reconfigure-cache");
async function setBranchStatus(branchName, description, state, context) {
    if (!is_1.default.nonEmptyString(context)) {
        // already logged this case when validating the status check
        return;
    }
    await platform_1.platform.setBranchStatus({
        branchName,
        context,
        description,
        state,
    });
}
function getReconfigureBranchName(prefix) {
    return `${prefix}reconfigure`;
}
exports.getReconfigureBranchName = getReconfigureBranchName;
async function validateReconfigureBranch(config) {
    logger_1.logger.debug('validateReconfigureBranch()');
    const context = config.statusCheckNames?.configValidation;
    const branchName = getReconfigureBranchName(config.branchPrefix);
    const branchExists = await scm_1.scm.branchExists(branchName);
    // this is something the user initiates, so skip if no branch exists
    if (!branchExists) {
        logger_1.logger.debug('No reconfigure branch found');
        (0, reconfigure_cache_1.deleteReconfigureBranchCache)(); // in order to remove cache when the branch has been deleted
        return;
    }
    // look for config file
    // 1. check reconfigure branch cache and use the configFileName if it exists
    // 2. checkout reconfigure branch and look for the config file, don't assume default configFileName
    const branchSha = (0, git_1.getBranchCommit)(branchName);
    const cache = (0, repository_1.getCache)();
    let configFileName = null;
    const reconfigureCache = cache.reconfigureBranchCache;
    // only use valid cached information
    if (reconfigureCache?.reconfigureBranchSha === branchSha) {
        logger_1.logger.debug('Skipping validation check as branch sha is unchanged');
        return;
    }
    if (context) {
        const validationStatus = await platform_1.platform.getBranchStatusCheck(branchName, context);
        // if old status check is present skip validation
        if (is_1.default.nonEmptyString(validationStatus)) {
            logger_1.logger.debug('Skipping validation check because status check already exists.');
            return;
        }
    }
    else {
        logger_1.logger.debug('Status check is null or an empty string, skipping status check addition.');
    }
    try {
        await scm_1.scm.checkoutBranch(branchName);
        configFileName = await (0, merge_1.detectConfigFile)();
    }
    catch (err) {
        logger_1.logger.error({ err }, 'Error while searching for config file in reconfigure branch');
    }
    if (!is_1.default.nonEmptyString(configFileName)) {
        logger_1.logger.warn('No config file found in reconfigure branch');
        await setBranchStatus(branchName, 'Validation Failed - No config file found', 'red', context);
        (0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
        await scm_1.scm.checkoutBranch(config.defaultBranch);
        return;
    }
    let configFileRaw = null;
    try {
        configFileRaw = await (0, fs_1.readLocalFile)(configFileName, 'utf8');
    }
    catch (err) {
        logger_1.logger.error({ err }, 'Error while reading config file');
    }
    if (!is_1.default.nonEmptyString(configFileRaw)) {
        logger_1.logger.warn('Empty or invalid config file');
        await setBranchStatus(branchName, 'Validation Failed - Empty/Invalid config file', 'red', context);
        (0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
        await scm_1.scm.checkoutBranch(config.baseBranch);
        return;
    }
    let configFileParsed;
    try {
        configFileParsed = json5_1.default.parse(configFileRaw);
        // no need to confirm renovate field in package.json we already do it in `detectConfigFile()`
        if (configFileName === 'package.json') {
            configFileParsed = configFileParsed.renovate;
        }
    }
    catch (err) {
        logger_1.logger.error({ err }, 'Error while parsing config file');
        await setBranchStatus(branchName, 'Validation Failed - Unparsable config file', 'red', context);
        (0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
        await scm_1.scm.checkoutBranch(config.baseBranch);
        return;
    }
    // perform validation and provide a passing or failing check run based on result
    const validationResult = await (0, validation_1.validateConfig)(configFileParsed);
    // failing check
    if (validationResult.errors.length > 0) {
        logger_1.logger.debug({ errors: validationResult.errors.map((err) => err.message).join(', ') }, 'Validation Errors');
        // add comment to reconfigure PR if it exists
        const branchPr = await platform_1.platform.getBranchPr(branchName, config.defaultBranch);
        if (branchPr) {
            let body = `There is an error with this repository's Renovate configuration that needs to be fixed.\n\n`;
            body += `Location: \`${configFileName}\`\n`;
            body += `Message: \`${validationResult.errors
                .map((e) => e.message)
                .join(', ')
                .replace((0, regex_1.regEx)(/`/g), "'")}\`\n`;
            await (0, comment_1.ensureComment)({
                number: branchPr.number,
                topic: 'Action Required: Fix Renovate Configuration',
                content: body,
            });
        }
        await setBranchStatus(branchName, 'Validation Failed', 'red', context);
        (0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, false);
        await scm_1.scm.checkoutBranch(config.baseBranch);
        return;
    }
    // passing check
    await setBranchStatus(branchName, 'Validation Successful', 'green', context);
    (0, reconfigure_cache_1.setReconfigureBranchCache)(branchSha, true);
    await scm_1.scm.checkoutBranch(config.baseBranch);
}
exports.validateReconfigureBranch = validateReconfigureBranch;
//# sourceMappingURL=index.js.map