"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parsePackagesResponses = exports.extractDepReleases = exports.extractReleaseResult = exports.parsePackagesResponse = exports.ComposerPackagesResponse = exports.ComposerReleases = exports.ComposerRelease = exports.MinifiedArray = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const zod_1 = require("zod");
const logger_1 = require("../../../logger");
exports.MinifiedArray = zod_1.z.array(zod_1.z.record(zod_1.z.unknown())).transform((xs) => {
    // Ported from: https://github.com/composer/metadata-minifier/blob/main/src/MetadataMinifier.php#L17
    if (xs.length === 0) {
        return xs;
    }
    const prevVals = {};
    for (const x of xs) {
        for (const key of Object.keys(x)) {
            prevVals[key] ?? (prevVals[key] = undefined);
        }
        for (const key of Object.keys(prevVals)) {
            const val = x[key];
            if (val === '__unset') {
                delete x[key];
                prevVals[key] = undefined;
                continue;
            }
            if (!is_1.default.undefined(val)) {
                prevVals[key] = val;
                continue;
            }
            if (!is_1.default.undefined(prevVals[key])) {
                x[key] = prevVals[key];
                continue;
            }
        }
    }
    return xs;
});
exports.ComposerRelease = zod_1.z
    .object({
    version: zod_1.z.string(),
})
    .merge(zod_1.z
    .object({
    homepage: zod_1.z.string().nullable().catch(null),
    source: zod_1.z
        .object({
        url: zod_1.z.string(),
    })
        .nullable()
        .catch(null),
    time: zod_1.z.string().nullable().catch(null),
    require: zod_1.z
        .object({
        php: zod_1.z.string(),
    })
        .nullable()
        .catch(null),
})
    .partial());
exports.ComposerReleases = zod_1.z
    .union([
    zod_1.z.array(exports.ComposerRelease.nullable().catch(null)),
    zod_1.z
        .record(exports.ComposerRelease.nullable().catch(null))
        .transform((map) => Object.values(map)),
])
    .catch([])
    .transform((xs) => xs.filter((x) => x !== null));
exports.ComposerPackagesResponse = zod_1.z.object({
    packages: zod_1.z.record(zod_1.z.unknown()),
});
function parsePackagesResponse(packageName, packagesResponse) {
    try {
        const { packages } = exports.ComposerPackagesResponse.parse(packagesResponse);
        const array = exports.MinifiedArray.parse(packages[packageName]);
        const releases = exports.ComposerReleases.parse(array);
        return releases;
    }
    catch (err) {
        logger_1.logger.debug({ packageName, err }, `Error parsing packagist response for ${packageName}`);
        return [];
    }
}
exports.parsePackagesResponse = parsePackagesResponse;
function extractReleaseResult(...composerReleasesArrays) {
    const releases = [];
    let homepage;
    let sourceUrl;
    for (const composerReleasesArray of composerReleasesArrays) {
        for (const composerRelease of composerReleasesArray) {
            const version = composerRelease.version.replace(/^v/, '');
            const gitRef = composerRelease.version;
            const dep = { version, gitRef };
            if (composerRelease.time) {
                dep.releaseTimestamp = composerRelease.time;
            }
            if (composerRelease.require?.php) {
                dep.constraints = { php: [composerRelease.require.php] };
            }
            releases.push(dep);
            if (!homepage && composerRelease.homepage) {
                homepage = composerRelease.homepage;
            }
            if (!sourceUrl && composerRelease.source?.url) {
                sourceUrl = composerRelease.source.url;
            }
        }
    }
    if (releases.length === 0) {
        return null;
    }
    const result = { releases };
    if (homepage) {
        result.homepage = homepage;
    }
    if (sourceUrl) {
        result.sourceUrl = sourceUrl;
    }
    return result;
}
exports.extractReleaseResult = extractReleaseResult;
function extractDepReleases(composerReleases) {
    const parsedReleases = exports.ComposerReleases.parse(composerReleases);
    return extractReleaseResult(parsedReleases);
}
exports.extractDepReleases = extractDepReleases;
function parsePackagesResponses(packageName, packagesResponses) {
    const releaseArrays = packagesResponses.map((pkgResp) => parsePackagesResponse(packageName, pkgResp));
    return extractReleaseResult(...releaseArrays);
}
exports.parsePackagesResponses = parsePackagesResponses;
//# sourceMappingURL=schema.js.map