"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractPackageFile = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const logger_1 = require("../../../logger");
const regex_1 = require("../../../util/regex");
const yaml_1 = require("../../../util/yaml");
const docker_1 = require("../../datasource/docker");
const helm_1 = require("../../datasource/helm");
const utils_1 = require("./utils");
const isValidChartName = (name) => !!name && !(0, regex_1.regEx)(/[!@#$%^&*(),.?":{}/|<>A-Z]/).test(name);
function isLocalPath(possiblePath) {
    return ['./', '../', '/'].some((localPrefix) => possiblePath.startsWith(localPrefix));
}
async function extractPackageFile(content, packageFile, config) {
    const deps = [];
    let docs;
    let registryAliases = {};
    // Record kustomization usage for all deps, since updating artifacts is run on the helmfile.yaml as a whole.
    let needKustomize = false;
    try {
        // TODO: use schema (#9610)
        docs = (0, yaml_1.parseYaml)(content, null, {
            removeTemplates: true,
            json: true,
        });
    }
    catch (err) {
        logger_1.logger.debug({ err, packageFile }, 'Failed to parse helmfile helmfile.yaml');
        return null;
    }
    for (const doc of docs) {
        if (!doc) {
            continue;
        }
        // Always check for repositories in the current document and override the existing ones if any (as YAML does)
        if (doc.repositories) {
            registryAliases = {};
            for (let i = 0; i < doc.repositories.length; i += 1) {
                registryAliases[doc.repositories[i].name] = doc.repositories[i].url;
            }
            logger_1.logger.debug({ registryAliases, packageFile }, `repositories discovered.`);
        }
        // Skip extraction if the document contains no releases
        if (!is_1.default.array(doc.releases)) {
            continue;
        }
        for (const dep of doc.releases) {
            let depName = dep.chart;
            let repoName = null;
            if (!is_1.default.string(dep.chart)) {
                deps.push({
                    depName: dep.name,
                    skipReason: 'invalid-name',
                });
                continue;
            }
            // If it starts with ./ ../ or / then it's a local path
            if (isLocalPath(dep.chart)) {
                if ((0, utils_1.kustomizationsKeysUsed)(dep) ||
                    (await (0, utils_1.localChartHasKustomizationsYaml)(dep, packageFile))) {
                    needKustomize = true;
                }
                deps.push({
                    depName: dep.name,
                    skipReason: 'local-chart',
                });
                continue;
            }
            if (is_1.default.number(dep.version)) {
                dep.version = String(dep.version);
            }
            if (dep.chart.includes('/')) {
                const v = dep.chart.split('/');
                repoName = v.shift();
                depName = v.join('/');
            }
            else {
                repoName = dep.chart;
            }
            if (!is_1.default.string(dep.version)) {
                deps.push({
                    depName,
                    skipReason: 'invalid-version',
                });
                continue;
            }
            const res = {
                depName,
                currentValue: dep.version,
                registryUrls: [registryAliases[repoName]]
                    .concat([config.registryAliases?.[repoName]])
                    .filter(is_1.default.string),
            };
            if ((0, utils_1.kustomizationsKeysUsed)(dep)) {
                needKustomize = true;
            }
            // in case of OCI repository, we need a PackageDependency with a DockerDatasource and a packageName
            const repository = doc.repositories?.find((repo) => repo.name === repoName);
            if (repository?.oci) {
                res.datasource = docker_1.DockerDatasource.id;
                res.packageName = registryAliases[repoName] + '/' + depName;
            }
            // By definition on helm the chart name should be lowercase letter + number + -
            // However helmfile support templating of that field
            if (!isValidChartName(res.depName)) {
                res.skipReason = 'unsupported-chart-type';
            }
            // Skip in case we cannot locate the registry
            if (is_1.default.emptyArray(res.registryUrls)) {
                res.skipReason = 'unknown-registry';
            }
            deps.push(res);
        }
    }
    return deps.length
        ? {
            deps,
            datasource: helm_1.HelmDatasource.id,
            ...(needKustomize && { managerData: { needKustomize } }),
        }
        : null;
}
exports.extractPackageFile = extractPackageFile;
//# sourceMappingURL=extract.js.map