"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GalaxyCollectionDatasource = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const logger_1 = require("../../../logger");
const decorator_1 = require("../../../util/cache/package/decorator");
const p = tslib_1.__importStar(require("../../../util/promises"));
const regex_1 = require("../../../util/regex");
const url_1 = require("../../../util/url");
const pep440Versioning = tslib_1.__importStar(require("../../versioning/pep440"));
const datasource_1 = require("../datasource");
const schema_1 = require("./schema");
const repositoryRegex = (0, regex_1.regEx)(/^\S+\/api\/galaxy\/content\/(?<repository>[^/]+)/);
class GalaxyCollectionDatasource extends datasource_1.Datasource {
    static id = 'galaxy-collection';
    constructor() {
        super(GalaxyCollectionDatasource.id);
    }
    customRegistrySupport = true;
    registryStrategy = 'hunt';
    defaultRegistryUrls = ['https://galaxy.ansible.com/api/'];
    defaultVersioning = pep440Versioning.id;
    releaseTimestampSupport = true;
    releaseTimestampNote = 'The release timestamp is determined from the `created_at` field in the results.';
    // sourceUrl is returned in each release as well as the ReleaseResult
    // the one present in release result is the sourceUrl of the latest release
    sourceUrlSupport = 'release';
    sourceUrlNote = 'The `sourceUrl` is determined from the `repository` field in the results.';
    async getReleases({ packageName, registryUrl, }) {
        const [namespace, projectName] = packageName.split('.');
        const repository = repositoryRegex.exec(registryUrl)?.groups?.repository ?? 'published';
        const baseUrl = (0, url_1.ensureTrailingSlash)((0, url_1.joinUrlParts)(registryUrl, 'v3/plugin/ansible/content', repository, 'collections/index', namespace, projectName));
        const { val: baseProject, err: baseErr } = await this.http
            .getJsonSafe(baseUrl, schema_1.GalaxyV3)
            .onError((err) => {
            logger_1.logger.warn({ datasource: this.id, packageName, err }, `Error fetching ${baseUrl}`);
        })
            .unwrap();
        if (baseErr) {
            this.handleGenericErrors(baseErr);
        }
        const versionsUrl = (0, url_1.ensureTrailingSlash)((0, url_1.joinUrlParts)(baseUrl, 'versions'));
        const { val: rawReleases, err: versionsErr } = await this.http
            .getJsonSafe(versionsUrl, schema_1.GalaxyV3Versions)
            .onError((err) => {
            logger_1.logger.warn({ datasource: this.id, packageName, err }, `Error fetching ${versionsUrl}`);
        })
            .unwrap();
        if (versionsErr) {
            this.handleGenericErrors(versionsErr);
        }
        const releases = rawReleases.map((value) => {
            return {
                ...value,
                isDeprecated: baseProject.deprecated,
            };
        });
        // asynchronously get release details
        const enrichedReleases = await p.map(releases, (release) => this.getVersionDetails(packageName, versionsUrl, release), { concurrency: 4 });
        // filter failed versions
        const filteredReleases = enrichedReleases.filter(is_1.default.truthy);
        // extract base information which are only provided on the release from the newest release
        // Find the source URL of the highest version release
        const sourceUrlOfHighestRelease = enrichedReleases.find((release) => baseProject.highest_version.version === release.version)?.sourceUrl;
        return {
            releases: filteredReleases,
            sourceUrl: sourceUrlOfHighestRelease,
        };
    }
    async getVersionDetails(packageName, versionsUrl, basicRelease) {
        const detailedVersionUrl = (0, url_1.ensureTrailingSlash)((0, url_1.joinUrlParts)(versionsUrl, basicRelease.version));
        const { val: rawDetailedVersion, err: versionsErr } = await this.http
            .getJsonSafe(detailedVersionUrl, schema_1.GalaxyV3DetailedVersion)
            .onError((err) => {
            logger_1.logger.warn({ datasource: this.id, packageName, err }, `Error fetching ${versionsUrl}`);
        })
            .unwrap();
        if (versionsErr) {
            this.handleGenericErrors(versionsErr);
        }
        return {
            ...rawDetailedVersion,
            isDeprecated: basicRelease.isDeprecated,
        };
    }
}
exports.GalaxyCollectionDatasource = GalaxyCollectionDatasource;
tslib_1.__decorate([
    (0, decorator_1.cache)({
        namespace: `datasource-${GalaxyCollectionDatasource.id}`,
        key: ({ packageName }) => `getReleases:${packageName}`,
    })
], GalaxyCollectionDatasource.prototype, "getReleases", null);
tslib_1.__decorate([
    (0, decorator_1.cache)({
        namespace: `datasource-${GalaxyCollectionDatasource.id}`,
        key: (_packageName, versionsUrl, basicRelease) => `getVersionDetails:${versionsUrl}:${basicRelease.version}`,
        ttlMinutes: 10080, // 1 week
    })
], GalaxyCollectionDatasource.prototype, "getVersionDetails", null);
//# sourceMappingURL=index.js.map