"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchUpdates = void 0;
const tslib_1 = require("tslib");
// TODO #22198
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const config_1 = require("../../../config");
const logger_1 = require("../../../logger");
const datasource_1 = require("../../../modules/datasource");
const common_1 = require("../../../modules/datasource/common");
const external_host_error_1 = require("../../../types/errors/external-host-error");
const memCache = tslib_1.__importStar(require("../../../util/cache/memory"));
const clone_1 = require("../../../util/clone");
const package_rules_1 = require("../../../util/package-rules");
const p = tslib_1.__importStar(require("../../../util/promises"));
const result_1 = require("../../../util/result");
const package_files_1 = require("../package-files");
const lookup_1 = require("./lookup");
async function withLookupStats(datasource, callback) {
    const start = Date.now();
    const result = await callback();
    const duration = Date.now() - start;
    const lookups = memCache.get('lookup-stats') || [];
    lookups.push({ datasource, duration });
    memCache.set('lookup-stats', lookups);
    return result;
}
async function fetchDepUpdates(packageFileConfig, indep) {
    const dep = (0, clone_1.clone)(indep);
    dep.updates = [];
    if (is_1.default.string(dep.depName)) {
        dep.depName = dep.depName.trim();
    }
    dep.packageName ??= dep.depName;
    if (!is_1.default.nonEmptyString(dep.packageName)) {
        dep.skipReason = 'invalid-name';
    }
    if (dep.isInternal && !packageFileConfig.updateInternalDeps) {
        dep.skipReason = 'internal-package';
    }
    if (dep.skipReason) {
        return result_1.Result.ok(dep);
    }
    const { depName } = dep;
    // TODO: fix types
    let depConfig = (0, config_1.mergeChildConfig)(packageFileConfig, dep);
    const datasourceDefaultConfig = await (0, datasource_1.getDefaultConfig)(depConfig.datasource);
    depConfig = (0, config_1.mergeChildConfig)(depConfig, datasourceDefaultConfig);
    depConfig.versioning ??= (0, common_1.getDefaultVersioning)(depConfig.datasource);
    depConfig = (0, package_rules_1.applyPackageRules)(depConfig);
    depConfig.packageName ??= depConfig.depName;
    if (depConfig.ignoreDeps.includes(depName)) {
        // TODO: fix types (#22198)
        logger_1.logger.debug(`Dependency: ${depName}, is ignored`);
        dep.skipReason = 'ignored';
    }
    else if (depConfig.enabled === false) {
        logger_1.logger.debug(`Dependency: ${depName}, is disabled`);
        dep.skipReason = 'disabled';
    }
    else {
        if (depConfig.datasource) {
            const { val: updateResult, err } = await withLookupStats(depConfig.datasource, () => result_1.Result.wrap((0, lookup_1.lookupUpdates)(depConfig)).unwrap());
            if (updateResult) {
                Object.assign(dep, updateResult);
            }
            else {
                if (packageFileConfig.repoIsOnboarded === true ||
                    !(err instanceof external_host_error_1.ExternalHostError)) {
                    return result_1.Result.err(err);
                }
                const cause = err.err;
                dep.warnings ??= [];
                dep.warnings.push({
                    topic: 'Lookup Error',
                    // TODO: types (#22198)
                    message: `${depName}: ${cause.message}`,
                });
            }
        }
        dep.updates ??= [];
    }
    return result_1.Result.ok(dep);
}
async function fetchManagerPackagerFileUpdates(config, managerConfig, pFile) {
    const { packageFile } = pFile;
    const packageFileConfig = (0, config_1.mergeChildConfig)(managerConfig, pFile);
    if (pFile.extractedConstraints) {
        packageFileConfig.constraints = {
            ...pFile.extractedConstraints,
            ...config.constraints,
        };
    }
    const { manager } = packageFileConfig;
    const queue = pFile.deps.map((dep) => async () => {
        const updates = await fetchDepUpdates(packageFileConfig, dep);
        return updates.unwrapOrThrow();
    });
    logger_1.logger.trace({ manager, packageFile, queueLength: queue.length }, 'fetchManagerPackagerFileUpdates starting with concurrency');
    pFile.deps = await p.all(queue);
    logger_1.logger.trace({ packageFile }, 'fetchManagerPackagerFileUpdates finished');
}
async function fetchManagerUpdates(config, packageFiles, manager) {
    const managerConfig = (0, config_1.getManagerConfig)(config, manager);
    const queue = packageFiles[manager].map((pFile) => () => fetchManagerPackagerFileUpdates(config, managerConfig, pFile));
    logger_1.logger.trace({ manager, queueLength: queue.length }, 'fetchManagerUpdates starting');
    await p.all(queue);
    logger_1.logger.trace({ manager }, 'fetchManagerUpdates finished');
}
async function fetchUpdates(config, packageFiles) {
    const managers = Object.keys(packageFiles);
    const allManagerJobs = managers.map((manager) => fetchManagerUpdates(config, packageFiles, manager));
    await Promise.all(allManagerJobs);
    package_files_1.PackageFiles.add(config.baseBranch, { ...packageFiles });
    logger_1.logger.debug({ baseBranch: config.baseBranch }, 'Package releases lookups complete');
}
exports.fetchUpdates = fetchUpdates;
//# sourceMappingURL=fetch.js.map