"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.requireManifestString = requireManifestString;
exports.getSupportedOsForManifestTarget = getSupportedOsForManifestTarget;
exports.createReleaseDownloadUrl = createReleaseDownloadUrl;
exports.createReleaseManifestSupportedPlatforms = createReleaseManifestSupportedPlatforms;
exports.validateManifestWebsiteRelativePath = validateManifestWebsiteRelativePath;
exports.validateManifestWebsiteDownloadPath = validateManifestWebsiteDownloadPath;
exports.validateManifestWebsiteDownloadUrl = validateManifestWebsiteDownloadUrl;
exports.normalizeReleaseManifestSupportedPlatforms = normalizeReleaseManifestSupportedPlatforms;
exports.normalizeReleaseManifestSupportedPlatform = normalizeReleaseManifestSupportedPlatform;
exports.validateReleaseManifestSupportedPlatforms = validateReleaseManifestSupportedPlatforms;
// Responsibility-focused extraction from output-lifecycle-manifest.ts.
const errors_1 = require("../../../lib/errors");
const output_lifecycle_output_state_1 = require("./output-lifecycle-output-state");
const output_lifecycle_payload_policy_1 = require("./output-lifecycle-payload-policy");
const output_lifecycle_manifest_normalization_1 = require("./output-lifecycle-manifest-normalization");
function requireManifestString(value, label, reason) {
    if (typeof value === 'string' && value.trim().length > 0) {
        return value;
    }
    throw (0, errors_1.createUsageError)(`Release manifest requires ${label}.`, [
        `Reason: ${reason}`,
        `Recovery: restore ${label} metadata before manifest generation.`,
        'Exit behavior: exits before successful-release state is recorded.',
    ]);
}
function getSupportedOsForManifestTarget(target) {
    if (target === 'windows' || target === 'windows-installer') {
        return ['win32'];
    }
    return ['darwin', 'linux'];
}
function createReleaseDownloadUrl(version, filename) {
    return new URL(`${version}/${filename}`, (0, output_lifecycle_manifest_normalization_1.normalizeDownloadOrigin)(output_lifecycle_output_state_1.DEFAULT_RELEASE_DOWNLOAD_ORIGIN)).toString();
}
function createReleaseManifestSupportedPlatforms() {
    return [
        {
            os: 'darwin',
            label: 'macOS',
            architectures: ['x64', 'arm64'],
            installer: 'posix',
        },
        {
            os: 'linux',
            label: 'Linux',
            architectures: ['x64', 'arm64'],
            installer: 'posix',
        },
        {
            os: 'win32',
            label: 'Windows',
            architectures: ['x64', 'arm64'],
            installer: 'powershell',
        },
    ];
}
function validateManifestWebsiteRelativePath(value, label) {
    const normalizedPath = (0, output_lifecycle_payload_policy_1.normalizePayloadPath)(value);
    if (normalizedPath.length === 0 ||
        normalizedPath.startsWith('/') ||
        normalizedPath.includes('://') ||
        normalizedPath.split('/').includes('..')) {
        throw (0, errors_1.createUsageError)(`Release manifest ${label} must be a website-relative placeholder path.`, [
            `Reason: manifest-${label.replace(/\s+/g, '-')}-invalid`,
            `${label}: ${value}`,
            'Recovery: keep manifest public paths as website-relative placeholders until website publication runs.',
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
}
function validateManifestWebsiteDownloadPath(value, version, filename, label) {
    const expectedPath = `downloads/${version}/${filename}`;
    if (value !== expectedPath || value.includes('/latest/')) {
        throw (0, errors_1.createUsageError)(`Release manifest ${label} must use an immutable versioned downloads path.`, [
            `Reason: manifest-${label.replace(/\s+/g, '-')}-invalid`,
            `Expected path: ${expectedPath}`,
            `Received path: ${value}`,
            'Recovery: regenerate the manifest from exact release version metadata.',
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
}
function validateManifestWebsiteDownloadUrl(value, version, filename, label) {
    const expectedUrl = createReleaseDownloadUrl(version, filename);
    if (value !== expectedUrl || value.includes('/latest/')) {
        throw (0, errors_1.createUsageError)(`Release manifest ${label} must use an immutable website-owned downloads URL.`, [
            `Reason: manifest-${label.replace(/\s+/g, '-')}-invalid`,
            `Expected URL: ${expectedUrl}`,
            `Received URL: ${value}`,
            'Recovery: regenerate the manifest from exact release version metadata.',
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
}
function normalizeReleaseManifestSupportedPlatforms(value) {
    if (!Array.isArray(value)) {
        throw (0, errors_1.createUsageError)('Release manifest supported platform metadata is missing or malformed.', [
            'Reason: malformed-manifest-supported-platforms',
            'Recovery: regenerate the manifest from release platform metadata.',
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
    return value.map((platform) => normalizeReleaseManifestSupportedPlatform(platform));
}
function normalizeReleaseManifestSupportedPlatform(value) {
    if (typeof value !== 'object' || value === null || Array.isArray(value)) {
        throw (0, errors_1.createUsageError)('Release manifest contains an invalid supported platform entry.', [
            'Reason: malformed-manifest-supported-platforms',
            'Recovery: regenerate the manifest from release platform metadata.',
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
    const platform = value;
    const os = platform.os;
    const label = platform.label;
    const architectures = platform.architectures;
    const installer = platform.installer;
    if (!['darwin', 'linux', 'win32'].includes(String(os)) ||
        !['macOS', 'Linux', 'Windows'].includes(String(label)) ||
        !Array.isArray(architectures) ||
        !architectures.every((architecture) => architecture === 'x64' || architecture === 'arm64') ||
        !['posix', 'powershell'].includes(String(installer))) {
        throw (0, errors_1.createUsageError)('Release manifest supported platform metadata is missing required fields.', [
            'Reason: malformed-manifest-supported-platforms',
            'Recovery: regenerate the manifest from release platform metadata.',
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
    return {
        os: os,
        label: label,
        architectures: architectures,
        installer: installer,
    };
}
function validateReleaseManifestSupportedPlatforms(platforms) {
    const expectedPlatforms = createReleaseManifestSupportedPlatforms();
    for (const expected of expectedPlatforms) {
        const platform = platforms.find((candidate) => candidate.os === expected.os);
        if (platform === undefined ||
            platform.label !== expected.label ||
            platform.installer !== expected.installer ||
            !expected.architectures.every((architecture) => platform.architectures.includes(architecture))) {
            throw (0, errors_1.createUsageError)('Release manifest supported platform metadata is incomplete.', [
                'Reason: manifest-supported-platforms-incomplete',
                `Expected platform: ${expected.os}`,
                'Recovery: regenerate the manifest from release platform metadata.',
                'Exit behavior: exits before successful-release state is recorded.',
            ]);
        }
    }
}
