"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createUnavailableMarkerState = createUnavailableMarkerState;
exports.resolveReleaseSuccessMarkerState = resolveReleaseSuccessMarkerState;
exports.getRootCommand = getRootCommand;
exports.addReleaseOptions = addReleaseOptions;
exports.renderReleaseContractSummary = renderReleaseContractSummary;
exports.formatReleaseOptionValue = formatReleaseOptionValue;
const output_1 = require("../../../lib/output");
const output_lifecycle_1 = require("./output-lifecycle");
const index_command_contracts_1 = require("./index-command-contracts");
function createUnavailableMarkerState() {
    return {
        present: false,
        valid: false,
        path: null,
        version: null,
        completedAt: null,
    };
}
function resolveReleaseSuccessMarkerState(options) {
    if (options.releaseSubcommand.name === 'build' && !options.dryRun && options.operation.changed) {
        return (0, output_lifecycle_1.writeReleaseSuccessMarker)({
            state: options.outputState,
            version: options.version,
            command: 'release build',
        });
    }
    return (0, output_lifecycle_1.readReleaseSuccessMarker)(options.outputState);
}
function getRootCommand(commandInstance) {
    let current = commandInstance;
    while (current?.parent != null) {
        current = current.parent;
    }
    return (current ?? commandInstance);
}
function addReleaseOptions(command, options) {
    if (options.includes('version')) {
        command
            .option('--release-version <version>', 'Explicit release version for the local release surface.')
            .addHelpText('after', '  --version <version>  Alias for --release-version on release subcommands.');
    }
    if (options.includes('commandName')) {
        command.option('--command-name <name>', 'Configured installed command basename used by release artifacts.', index_command_contracts_1.DEFAULT_INSTALLED_COMMAND_NAME);
    }
    if (options.includes('outputDir')) {
        command.option('--output-dir <path>', 'Generated local release output root.');
    }
    if (options.includes('keep')) {
        command.option('--keep <count>', 'Number of successful prior local release directories to keep.', '3');
    }
    if (options.includes('confirm')) {
        command.option('--confirm', 'Acknowledge that future cleanup is an explicit generated-output cleanup operation.');
    }
    if (options.includes('dryRun')) {
        command.option('--dry-run', 'Report the release command contract without generating, pruning, or deleting files.');
    }
    if (options.includes('dirty')) {
        command.option('--dirty', 'Permit uncommitted local changes and route release build output to dirty-release/<version> by default.');
    }
}
function renderReleaseContractSummary(data) {
    return [
        (0, output_1.renderTerminalHeading)('Release command surface', 'title'),
        (0, output_1.renderTerminalSection)({
            heading: 'Contract',
            headingStyle: 'section',
            fields: [
                { label: 'Command', value: data.command },
                { label: 'Mode', value: data.mode },
                { label: 'Boundary', value: data.boundary },
                { label: 'Release output root', value: data.output.releaseRootRelative },
                { label: 'Version directory', value: data.output.versionDirectoryRelative ?? '(not applicable)' },
                { label: 'Staging directory', value: data.output.stagingDirectoryRelative ?? '(not applicable)' },
                { label: 'Success marker', value: data.successMarker.valid ? 'present' : 'not present' },
                { label: 'Build preflight', value: data.buildPreflight.status },
                { label: 'Test receipt', value: data.buildPreflight.testReceipt.status },
                { label: 'Dist payload', value: data.buildPreflight.dist.status },
                { label: 'Staging payload', value: data.stagingPayload.status },
                { label: 'Archive payloads', value: data.archivePayloads.status },
                { label: 'Installer assets', value: data.installerAssets.status },
                { label: 'Checksums', value: data.artifactChecksums.status },
                { label: 'Manifest', value: data.releaseManifest.status },
                { label: 'Download bundle', value: data.downloadBundle.status },
                { label: 'Installation README', value: data.installationReadme.status },
                { label: 'Installer safety validation', value: data.installerSafetyValidation.status },
                { label: 'Local release validation', value: data.localValidation.status },
                { label: 'Local validation report', value: data.localValidationReport.status },
                { label: 'Local output changed', value: data.operation.changed },
                { label: 'Clean repository required', value: data.repositoryState.cleanRequired },
                { label: 'Dirty release mode', value: data.repositoryState.dirtyAllowed },
                { label: 'Dirty repository paths', value: data.repositoryState.dirtyPaths.length },
                { label: 'Ignored generated output paths', value: data.repositoryState.ignoredGeneratedOutputPaths.length },
                { label: 'Website upload', value: data.publication.websiteUpload },
                { label: 'Public npm publication', value: data.publication.publicNpmPublication },
                { label: 'Next implementation', value: data.nextImplementation },
            ],
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: 'Build preflight',
            headingStyle: 'section',
            entries: data.buildPreflight.steps.length === 0
                ? [{ label: 'not-applicable', fields: [{ label: 'Required', value: data.buildPreflight.required }] }]
                : data.buildPreflight.steps.map((step) => ({
                    label: step.name,
                    fields: [
                        { label: 'Status', value: step.status },
                        { label: 'Command', value: step.command.join(' ') },
                    ],
                })),
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Test receipt',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.buildPreflight.testReceipt.status },
                { label: 'Receipt status', value: data.buildPreflight.testReceipt.receiptStatus },
                { label: 'Suite identity', value: data.buildPreflight.testReceipt.suiteIdentity ?? '(not applicable)' },
                { label: 'Suite executions', value: data.buildPreflight.testReceipt.suiteExecutions },
                { label: 'Reason', value: data.buildPreflight.testReceipt.reason },
                { label: 'Selected files', value: data.buildPreflight.testReceipt.counters.selected },
                { label: 'Reused files', value: data.buildPreflight.testReceipt.counters.reused },
                { label: 'Executed files', value: data.buildPreflight.testReceipt.counters.executed },
                { label: 'Invalidated files', value: data.buildPreflight.testReceipt.counters.invalidated },
                { label: 'Remaining files', value: data.buildPreflight.testReceipt.counters.remaining },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Dist payload',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.buildPreflight.dist.status },
                { label: 'Path', value: data.buildPreflight.dist.path ?? '(not applicable)' },
                { label: 'Required entrypoint', value: data.buildPreflight.dist.requiredEntrypoint ?? '(not applicable)' },
                { label: 'Required entrypoint present', value: data.buildPreflight.dist.requiredEntrypointPresent },
                { label: 'File count', value: data.buildPreflight.dist.fileCount },
                { label: 'Build input manifest', value: data.buildPreflight.dist.manifestPath ?? '(none)' },
                { label: 'Build input digest', value: data.buildPreflight.dist.manifestDigest ?? '(none)' },
                { label: 'Distribution identity', value: data.buildPreflight.dist.distributionIdentity ?? '(none)' },
                { label: 'Freshness reason', value: data.buildPreflight.dist.freshnessReason ?? '(none)' },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Staging payload',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.stagingPayload.status },
                { label: 'Staging directory', value: data.stagingPayload.stagingDirectory ?? '(not applicable)' },
                { label: 'Production dependencies', value: data.stagingPayload.productionDependencies.length },
                { label: 'Notice files', value: data.stagingPayload.noticeFiles.length },
                { label: 'Launchers', value: data.stagingPayload.launchers.length },
                { label: 'Files', value: data.stagingPayload.files.length },
            ],
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: 'Archive payloads',
            headingStyle: 'section',
            entries: data.archivePayloads.targets.length === 0
                ? [
                    {
                        label: data.archivePayloads.status,
                        fields: [{ label: 'Root directory', value: data.archivePayloads.rootDirectory ?? '(not applicable)' }],
                    },
                ]
                : data.archivePayloads.targets.map((target) => ({
                    label: target.target,
                    fields: [
                        { label: 'Payload directory', value: target.payloadDirectory },
                        { label: 'Archive filename', value: target.archiveFilename },
                        { label: 'Archive path', value: target.archivePath },
                        { label: 'Launchers', value: target.launcherPaths.join(', ') },
                        { label: 'Files', value: target.files.length },
                    ],
                })),
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Artifact checksums',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.artifactChecksums.status },
                { label: 'Checksum JSON', value: data.artifactChecksums.checksumJsonPath ?? '(not applicable)' },
                { label: 'Checksum text', value: data.artifactChecksums.checksumTextPath ?? '(not applicable)' },
                { label: 'Artifacts', value: data.artifactChecksums.artifacts.length },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Download bundle',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.downloadBundle.status },
                { label: 'Directory', value: data.downloadBundle.directory ?? '(not applicable)' },
                { label: 'Files', value: data.downloadBundle.files.length },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Installation README',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.installationReadme.status },
                { label: 'Path', value: data.installationReadme.path ?? '(not applicable)' },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Installer safety validation',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.installerSafetyValidation.status },
                { label: 'Install root', value: data.installerSafetyValidation.installRoot ?? '(not applicable)' },
                { label: 'Targets', value: data.installerSafetyValidation.targets.length },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Local release validation',
            headingStyle: 'section',
            fields: [
                { label: 'Status', value: data.localValidation.status },
                { label: 'Staging executable', value: data.localValidation.staging?.executable ?? '(not applicable)' },
                { label: 'Staging commands', value: data.localValidation.staging?.commands.length ?? 0 },
                { label: 'Archive validations', value: data.localValidation.archives.length },
                {
                    label: 'Archive executions',
                    value: data.localValidation.archives.filter((target) => target.execution !== null).length,
                },
                { label: 'Report', value: data.localValidationReport.reportPathRelative ?? '(not applicable)' },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Package boundary',
            headingStyle: 'section',
            fields: [
                { label: 'Package metadata', value: data.packageBoundary.packageJsonPath },
                { label: 'Private package', value: data.packageBoundary.private },
                {
                    label: 'Package bin',
                    value: data.packageBoundary.packageBinName === null
                        ? '(missing)'
                        : `${data.packageBoundary.packageBinName} -> ${data.packageBoundary.packageBinPath}`,
                },
                { label: 'Installed command', value: data.packageBoundary.installedCommandName },
                { label: 'Node engine', value: data.packageBoundary.engines.node ?? '(missing)' },
                { label: 'Package manager', value: data.packageBoundary.packageManager ?? '(missing)' },
                { label: 'Public registry install', value: data.packageBoundary.publication.publicRegistryInstall },
            ],
        }),
        (0, output_1.renderTerminalSection)({
            heading: 'Local output operation',
            headingStyle: 'section',
            fields: [
                { label: 'Kind', value: data.operation.kind },
                { label: 'Dry run', value: data.operation.dryRun },
                { label: 'Message', value: data.operation.message },
                { label: 'Published artifacts affected', value: 'none' },
            ],
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: 'Command invocations',
            headingStyle: 'section',
            entries: data.invocation === null
                ? [
                    {
                        label: 'unavailable',
                        fields: [
                            { label: 'Reason', value: 'command-name metadata is not configured for this release subcommand' },
                        ],
                    },
                ]
                : [
                    {
                        label: 'development',
                        fields: [{ label: 'Command', value: data.invocation.development.command.join(' ') }],
                    },
                    {
                        label: 'staged-release',
                        fields: [{ label: 'Command', value: data.invocation.stagedRelease.command.join(' ') }],
                    },
                    {
                        label: 'installed-user',
                        fields: [{ label: 'Command', value: data.invocation.installedUser.command.join(' ') }],
                    },
                ],
        }),
        (0, output_1.renderTerminalCompactList)({
            heading: 'Options',
            headingStyle: 'section',
            entries: [
                {
                    label: 'version',
                    fields: [{ label: 'Value', value: formatReleaseOptionValue(data.options.version, '(not provided)') }],
                },
                {
                    label: 'command-name',
                    fields: [{ label: 'Value', value: formatReleaseOptionValue(data.options.commandName, '(not applicable)') }],
                },
                {
                    label: 'output-dir',
                    fields: [{ label: 'Value', value: formatReleaseOptionValue(data.options.outputDir, 'release') }],
                },
                {
                    label: 'keep',
                    fields: [{ label: 'Value', value: formatReleaseOptionValue(data.options.keep, '(not applicable)') }],
                },
                { label: 'confirm', fields: [{ label: 'Value', value: data.options.confirm }] },
                { label: 'dry-run', fields: [{ label: 'Value', value: data.options.dryRun }] },
                { label: 'dirty', fields: [{ label: 'Value', value: data.options.dirty }] },
            ],
        }),
        data.options.dryRun
            ? (0, output_1.renderTerminalBoundary)({ kind: 'dry-run' })
            : (0, output_1.renderTerminalBoundary)({
                kind: 'mutating-no-op',
                reason: 'This milestone declares release command surfaces only; payload writes and cleanup are implemented by later milestones.',
            }),
    ].join('\n');
}
function formatReleaseOptionValue(value, fallback) {
    if (value === undefined || value === null || value === '') {
        return fallback;
    }
    return String(value);
}
