"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.populateReleaseManifest = populateReleaseManifest;
// Responsibility-focused extraction from output-lifecycle-manifest.ts.
const node_crypto_1 = __importDefault(require("node:crypto"));
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../../../lib/errors");
const output_lifecycle_installer_safety_1 = require("./output-lifecycle-installer-safety");
const output_lifecycle_lifecycle_contracts_1 = require("./output-lifecycle-lifecycle-contracts");
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_staging_1 = require("./output-lifecycle-staging");
const output_lifecycle_manifest_platforms_1 = require("./output-lifecycle-manifest-platforms");
function populateReleaseManifest(options) {
    if (options.state.versionDirectory === null || options.state.versionDirectoryRelative === null) {
        throw (0, errors_1.createUsageError)('Release manifest generation requires a resolved version directory.', [
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
    if (options.artifactChecksums.status !== 'created') {
        return (0, output_lifecycle_output_state_1.createNotApplicableReleaseManifest)();
    }
    const bundleDirectory = (0, output_lifecycle_staging_1.resolveReleaseDownloadBundleDirectory)(options.state);
    const bundleDirectoryRelative = (0, output_lifecycle_staging_1.resolveReleaseDownloadBundleRelativeDirectory)(options.state);
    if (bundleDirectory === null || bundleDirectoryRelative === null) {
        throw (0, errors_1.createUsageError)('Release manifest generation requires a resolved download bundle directory.', [
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
    node_fs_1.default.mkdirSync(bundleDirectory, { recursive: true });
    const manifestPath = node_path_1.default.join(bundleDirectory, output_lifecycle_output_state_1.RELEASE_MANIFEST_FILENAME);
    const manifestPathRelative = `${bundleDirectoryRelative}/${output_lifecycle_output_state_1.RELEASE_MANIFEST_FILENAME}`;
    const releaseNotesPath = `${bundleDirectoryRelative}/${output_lifecycle_output_state_1.RELEASE_NOTES_FILENAME}`;
    const releaseNotesFilePath = node_path_1.default.join(bundleDirectory, output_lifecycle_output_state_1.RELEASE_NOTES_FILENAME);
    const releaseNotesSourceSummary = {
        ...options.releaseNotesSourceSummary,
        status: node_fs_1.default.existsSync(releaseNotesFilePath) ? 'generated' : options.releaseNotesSourceSummary.status,
    };
    const installerManifest = {
        schemaVersion: 1,
        generatedBy: 'day-shift-release',
        version: options.version,
        command: {
            installedName: options.installedCommandName,
        },
        runtime: {
            model: 'system-node',
            requiredNodeVersion: (0, output_lifecycle_manifest_platforms_1.requireManifestString)(options.requiredNodeVersion, 'Node.js requirement', 'missing-node-version-requirement'),
        },
        artifacts: options.artifactChecksums.artifacts
            .filter((artifact) => artifact.kind === 'archive')
            .map((artifact) => ({
            kind: artifact.kind,
            target: artifact.target,
            filename: artifact.filename,
            byteSize: artifact.byteSize,
            sha256: artifact.sha256,
            runtimeModel: 'system-node',
        })),
    };
    const installerManifestReference = writeReferencedReleaseJson({
        bundleDirectory,
        bundleDirectoryRelative,
        version: options.version,
        filename: output_lifecycle_output_state_1.RELEASE_INSTALLER_MANIFEST_FILENAME,
        data: installerManifest,
    });
    const releaseNotesProvenance = {
        schemaVersion: 1,
        generatedBy: 'day-shift-release',
        version: options.version,
        sourceSummary: releaseNotesSourceSummary,
    };
    const releaseNotesProvenanceReference = writeReferencedReleaseJson({
        bundleDirectory,
        bundleDirectoryRelative,
        version: options.version,
        filename: output_lifecycle_output_state_1.RELEASE_NOTES_PROVENANCE_FILENAME,
        data: releaseNotesProvenance,
    });
    const manifest = {
        schemaVersion: 1,
        generatedBy: 'day-shift-release',
        cliVersion: (0, output_lifecycle_manifest_platforms_1.requireManifestString)(options.cliVersion, 'CLI version', 'missing-cli-version'),
        version: options.version,
        releaseDate: new Date().toISOString().slice(0, 10),
        status: 'active',
        command: {
            installedName: options.installedCommandName,
            stagedCommandPath: (0, output_lifecycle_payload_policy_1.normalizePayloadPath)(options.stagedCommandPath),
            invocations: {
                development: 'node dist/cli/index.js',
                stagedRelease: (0, output_lifecycle_payload_policy_1.normalizePayloadPath)(options.stagedCommandPath),
                installedUser: options.installedCommandName,
            },
        },
        runtime: {
            model: 'system-node',
            requiredNodeVersion: (0, output_lifecycle_manifest_platforms_1.requireManifestString)(options.requiredNodeVersion, 'Node.js requirement', 'missing-node-version-requirement'),
            productionDependenciesIncluded: true,
        },
        supportedPlatforms: (0, output_lifecycle_manifest_platforms_1.createReleaseManifestSupportedPlatforms)(),
        installation: {
            readmePath: `${bundleDirectoryRelative}/${output_lifecycle_output_state_1.RELEASE_INSTALLATION_README_FILENAME}`,
            installerManifest: installerManifestReference,
            defaultInstallDirectory: {
                posix: output_lifecycle_output_state_1.DEFAULT_POSIX_INSTALL_DIRECTORY,
                windows: output_lifecycle_output_state_1.DEFAULT_WINDOWS_INSTALL_DIRECTORY,
            },
            defaultBinDirectory: {
                posix: output_lifecycle_output_state_1.DEFAULT_POSIX_BIN_DIRECTORY,
                windows: output_lifecycle_output_state_1.DEFAULT_WINDOWS_BIN_DIRECTORY,
            },
        },
        compatibility: output_lifecycle_lifecycle_contracts_1.CURRENT_RELEASE_COMPATIBILITY,
        artifacts: options.artifactChecksums.artifacts.map((artifact) => ({
            kind: artifact.kind,
            target: artifact.target,
            filename: artifact.filename,
            path: artifact.path,
            downloadPath: `downloads/${options.version}/${artifact.filename}`,
            url: (0, output_lifecycle_manifest_platforms_1.createReleaseDownloadUrl)(options.version, artifact.filename),
            byteSize: artifact.byteSize,
            sha256: artifact.sha256,
            runtimeModel: 'system-node',
            supportedOs: (0, output_lifecycle_manifest_platforms_1.getSupportedOsForManifestTarget)(artifact.target),
            supportedArch: ['x64', 'arm64'],
        })),
        releaseNotes: {
            path: releaseNotesPath,
            url: (0, output_lifecycle_manifest_platforms_1.createReleaseDownloadUrl)(options.version, output_lifecycle_output_state_1.RELEASE_NOTES_FILENAME),
            sourceSummary: {
                status: releaseNotesSourceSummary.status,
                counts: releaseNotesSourceSummary.counts,
                provenance: releaseNotesProvenanceReference,
            },
        },
        replacement: {
            status: 'active',
            replacementVersion: null,
            replacementManifestPath: null,
            reason: null,
        },
        publication: {
            websiteUpload: 'out-of-scope',
            publicNpmPublication: 'out-of-scope',
        },
    };
    (0, output_lifecycle_installer_safety_1.validateReleaseManifest)({
        versionDirectory: options.state.versionDirectory,
        versionDirectoryRelative: options.state.versionDirectoryRelative,
        expectedVersion: options.version,
        expectedInstalledCommandName: options.installedCommandName,
        expectedStagedCommandPath: options.stagedCommandPath,
        expectedArtifactPaths: options.artifactChecksums.artifacts.map((artifact) => artifact.path),
        manifest,
    });
    node_fs_1.default.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
    return {
        status: 'created',
        manifestPath: manifestPathRelative,
        installerManifestPath: installerManifestReference.path,
        releaseNotesProvenancePath: releaseNotesProvenanceReference.path,
        data: manifest,
    };
}
function writeReferencedReleaseJson(options) {
    const text = `${JSON.stringify(options.data, null, 2)}\n`;
    const filePath = node_path_1.default.join(options.bundleDirectory, options.filename);
    const relativePath = `${options.bundleDirectoryRelative}/${options.filename}`;
    node_fs_1.default.writeFileSync(filePath, text);
    return {
        filename: options.filename,
        path: relativePath,
        downloadPath: `downloads/${options.version}/${options.filename}`,
        url: (0, output_lifecycle_manifest_platforms_1.createReleaseDownloadUrl)(options.version, options.filename),
        byteSize: Buffer.byteLength(text),
        sha256: node_crypto_1.default.createHash('sha256').update(text).digest('hex'),
    };
}
