"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RELEASE_WINDOWS_UNINSTALLER_FILENAME = exports.RELEASE_WINDOWS_INSTALLER_FILENAME = exports.RELEASE_POSIX_UNINSTALLER_FILENAME = exports.RELEASE_POSIX_INSTALLER_FILENAME = exports.RELEASE_NOTES_PROVENANCE_FILENAME = exports.RELEASE_NOTES_FILENAME = exports.RELEASE_MANIFEST_FILENAME = exports.RELEASE_INSTALLER_MANIFEST_FILENAME = exports.RELEASE_INSTALLATION_README_FILENAME = exports.RELEASE_DOWNLOAD_BUNDLE_DIRECTORY = exports.RELEASE_CHECKSUMS_FILENAME = exports.RELEASE_ARTIFACT_CHECKSUMS_FILENAME = exports.PUBLIC_CLI_EXCLUDED_PRIVATE_RUNTIME_FILES = exports.DEFAULT_WINDOWS_INSTALL_DIRECTORY = exports.DEFAULT_WINDOWS_BIN_DIRECTORY = exports.DEFAULT_RELEASE_DOWNLOAD_ORIGIN = exports.DEFAULT_POSIX_INSTALL_DIRECTORY = exports.DEFAULT_POSIX_BIN_DIRECTORY = void 0;
exports.resolveReleaseOutputState = resolveReleaseOutputState;
exports.prepareFreshReleaseBuildDirectory = prepareFreshReleaseBuildDirectory;
exports.writeReleaseSuccessMarker = writeReleaseSuccessMarker;
exports.readReleaseSuccessMarker = readReleaseSuccessMarker;
exports.createDryRunOperation = createDryRunOperation;
exports.createSkippedStagingPayload = createSkippedStagingPayload;
exports.createNotApplicableStagingPayload = createNotApplicableStagingPayload;
exports.createSkippedArchivePayloads = createSkippedArchivePayloads;
exports.createNotApplicableArchivePayloads = createNotApplicableArchivePayloads;
exports.createSkippedArtifactChecksums = createSkippedArtifactChecksums;
exports.createSkippedInstallerAssets = createSkippedInstallerAssets;
exports.createNotApplicableInstallerAssets = createNotApplicableInstallerAssets;
exports.createNotApplicableArtifactChecksums = createNotApplicableArtifactChecksums;
exports.createSkippedReleaseManifest = createSkippedReleaseManifest;
exports.createSkippedInstallationReadme = createSkippedInstallationReadme;
exports.createSkippedDownloadBundle = createSkippedDownloadBundle;
exports.createNotApplicableInstallationReadme = createNotApplicableInstallationReadme;
exports.createNotApplicableDownloadBundle = createNotApplicableDownloadBundle;
exports.createNotApplicableReleaseManifest = createNotApplicableReleaseManifest;
// Mechanically extracted from output-lifecycle.ts to keep release responsibilities bounded.
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const cli_constants_1 = require("../../../lib/config/cli-constants");
Object.defineProperty(exports, "DEFAULT_POSIX_BIN_DIRECTORY", { enumerable: true, get: function () { return cli_constants_1.DEFAULT_POSIX_BIN_DIRECTORY; } });
Object.defineProperty(exports, "DEFAULT_POSIX_INSTALL_DIRECTORY", { enumerable: true, get: function () { return cli_constants_1.DEFAULT_POSIX_INSTALL_DIRECTORY; } });
Object.defineProperty(exports, "DEFAULT_RELEASE_DOWNLOAD_ORIGIN", { enumerable: true, get: function () { return cli_constants_1.DEFAULT_RELEASE_DOWNLOAD_ORIGIN; } });
Object.defineProperty(exports, "DEFAULT_WINDOWS_BIN_DIRECTORY", { enumerable: true, get: function () { return cli_constants_1.DEFAULT_WINDOWS_BIN_DIRECTORY; } });
Object.defineProperty(exports, "DEFAULT_WINDOWS_INSTALL_DIRECTORY", { enumerable: true, get: function () { return cli_constants_1.DEFAULT_WINDOWS_INSTALL_DIRECTORY; } });
Object.defineProperty(exports, "PUBLIC_CLI_EXCLUDED_PRIVATE_RUNTIME_FILES", { enumerable: true, get: function () { return cli_constants_1.PUBLIC_CLI_EXCLUDED_PRIVATE_RUNTIME_FILES; } });
Object.defineProperty(exports, "RELEASE_ARTIFACT_CHECKSUMS_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_ARTIFACT_CHECKSUMS_FILENAME; } });
Object.defineProperty(exports, "RELEASE_CHECKSUMS_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_CHECKSUMS_FILENAME; } });
Object.defineProperty(exports, "RELEASE_DOWNLOAD_BUNDLE_DIRECTORY", { enumerable: true, get: function () { return cli_constants_1.RELEASE_DOWNLOAD_BUNDLE_DIRECTORY; } });
Object.defineProperty(exports, "RELEASE_INSTALLATION_README_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_INSTALLATION_README_FILENAME; } });
Object.defineProperty(exports, "RELEASE_INSTALLER_MANIFEST_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_INSTALLER_MANIFEST_FILENAME; } });
Object.defineProperty(exports, "RELEASE_MANIFEST_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_MANIFEST_FILENAME; } });
Object.defineProperty(exports, "RELEASE_NOTES_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_NOTES_FILENAME; } });
Object.defineProperty(exports, "RELEASE_NOTES_PROVENANCE_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_NOTES_PROVENANCE_FILENAME; } });
Object.defineProperty(exports, "RELEASE_POSIX_INSTALLER_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_POSIX_INSTALLER_FILENAME; } });
Object.defineProperty(exports, "RELEASE_POSIX_UNINSTALLER_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_POSIX_UNINSTALLER_FILENAME; } });
Object.defineProperty(exports, "RELEASE_WINDOWS_INSTALLER_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_WINDOWS_INSTALLER_FILENAME; } });
Object.defineProperty(exports, "RELEASE_WINDOWS_UNINSTALLER_FILENAME", { enumerable: true, get: function () { return cli_constants_1.RELEASE_WINDOWS_UNINSTALLER_FILENAME; } });
const errors_1 = require("../../../lib/errors");
const output_lifecycle_lifecycle_contracts_1 = require("./output-lifecycle-lifecycle-contracts");
const output_lifecycle_payload_policy_1 = require("./output-lifecycle-payload-policy");
const output_lifecycle_staging_1 = require("./output-lifecycle-staging");
function resolveReleaseOutputState(options) {
    const repositoryRoot = node_path_1.default.resolve(options.repositoryRoot);
    const releaseRoot = (0, output_lifecycle_staging_1.resolvePathWithinRepository)({
        repositoryRoot,
        value: options.outputDir,
        fallback: 'release',
        label: 'release output root',
    });
    const versionDirectory = options.version === null ? null : node_path_1.default.join(releaseRoot, options.version);
    const stagingDirectory = versionDirectory === null ? null : node_path_1.default.join(versionDirectory, 'staging');
    return {
        releaseRoot,
        releaseRootRelative: (0, output_lifecycle_payload_policy_1.toRepositoryRelativePath)(repositoryRoot, releaseRoot),
        versionDirectory,
        versionDirectoryRelative: versionDirectory === null ? null : (0, output_lifecycle_payload_policy_1.toRepositoryRelativePath)(repositoryRoot, versionDirectory),
        stagingDirectory,
        stagingDirectoryRelative: stagingDirectory === null ? null : (0, output_lifecycle_payload_policy_1.toRepositoryRelativePath)(repositoryRoot, stagingDirectory),
        successMarkerPath: versionDirectory === null ? null : node_path_1.default.join(versionDirectory, output_lifecycle_lifecycle_contracts_1.RELEASE_SUCCESS_MARKER_FILE),
        successMarkerPathRelative: versionDirectory === null
            ? null
            : (0, output_lifecycle_payload_policy_1.toRepositoryRelativePath)(repositoryRoot, node_path_1.default.join(versionDirectory, output_lifecycle_lifecycle_contracts_1.RELEASE_SUCCESS_MARKER_FILE)),
    };
}
function prepareFreshReleaseBuildDirectory(state) {
    if (state.versionDirectory === null ||
        state.versionDirectoryRelative === null ||
        state.stagingDirectory === null ||
        state.stagingDirectoryRelative === null) {
        throw (0, errors_1.createUsageError)('Release build requires a resolved version directory.', [
            'Exit behavior: exits before generated release output directories or artifacts are created.',
        ]);
    }
    if (node_fs_1.default.existsSync(state.versionDirectory)) {
        throw (0, errors_1.createUsageError)(`Release output directory already exists: ${state.versionDirectoryRelative}`, [
            'Reason: stale-or-partial-version-directory',
            'Recovery: choose a new release version or run release cleanup for generated local output.',
            'Exit behavior: exits before generated release output directories or artifacts are created.',
        ]);
    }
    node_fs_1.default.mkdirSync(state.stagingDirectory, { recursive: true });
    return {
        kind: 'fresh-staging-directory',
        dryRun: false,
        changed: true,
        removedPaths: [],
        retainedPaths: [state.versionDirectoryRelative, state.stagingDirectoryRelative],
        message: `Created fresh local release staging directory ${state.stagingDirectoryRelative}.`,
    };
}
function writeReleaseSuccessMarker(options) {
    if (options.state.versionDirectory === null ||
        options.state.successMarkerPath === null ||
        options.state.successMarkerPathRelative === null) {
        throw (0, errors_1.createUsageError)('Release success marker requires a resolved version directory.', [
            'Exit behavior: exits before successful-release state is recorded.',
        ]);
    }
    const marker = {
        marker: 'day-shift-release-success',
        version: options.version,
        command: options.command,
        outputRoot: options.state.releaseRootRelative,
        completedAt: new Date().toISOString(),
    };
    node_fs_1.default.writeFileSync(options.state.successMarkerPath, `${JSON.stringify(marker, null, 2)}\n`);
    return {
        present: true,
        valid: true,
        path: options.state.successMarkerPathRelative,
        version: marker.version,
        completedAt: marker.completedAt,
    };
}
function readReleaseSuccessMarker(state) {
    if (state.successMarkerPath === null || state.successMarkerPathRelative === null) {
        return {
            present: false,
            valid: false,
            path: null,
            version: null,
            completedAt: null,
        };
    }
    if (!node_fs_1.default.existsSync(state.successMarkerPath)) {
        return {
            present: false,
            valid: false,
            path: state.successMarkerPathRelative,
            version: null,
            completedAt: null,
        };
    }
    try {
        const marker = JSON.parse(node_fs_1.default.readFileSync(state.successMarkerPath, 'utf8'));
        const valid = marker.marker === 'day-shift-release-success' &&
            typeof marker.version === 'string' &&
            marker.version.length > 0 &&
            typeof marker.completedAt === 'string' &&
            marker.completedAt.length > 0;
        return {
            present: true,
            valid,
            path: state.successMarkerPathRelative,
            version: typeof marker.version === 'string' ? marker.version : null,
            completedAt: typeof marker.completedAt === 'string' ? marker.completedAt : null,
        };
    }
    catch {
        return {
            present: true,
            valid: false,
            path: state.successMarkerPathRelative,
            version: null,
            completedAt: null,
        };
    }
}
function createDryRunOperation(kind, message) {
    return {
        kind,
        dryRun: true,
        changed: false,
        removedPaths: [],
        retainedPaths: [],
        message,
    };
}
function createSkippedStagingPayload(state) {
    return {
        status: 'skipped-dry-run',
        stagingDirectory: state.stagingDirectoryRelative,
        files: [],
        launchers: [],
        productionDependencies: [],
        noticeFiles: [],
        validation: null,
    };
}
function createNotApplicableStagingPayload() {
    return {
        status: 'not-applicable',
        stagingDirectory: null,
        files: [],
        launchers: [],
        productionDependencies: [],
        noticeFiles: [],
        validation: null,
    };
}
function createSkippedArchivePayloads(state) {
    return {
        status: 'skipped-dry-run',
        rootDirectory: state.versionDirectoryRelative === null ? null : `${state.versionDirectoryRelative}/archive-payloads`,
        targets: [],
    };
}
function createNotApplicableArchivePayloads() {
    return {
        status: 'not-applicable',
        rootDirectory: null,
        targets: [],
    };
}
function createSkippedArtifactChecksums(state) {
    const bundleDirectory = (0, output_lifecycle_staging_1.resolveReleaseDownloadBundleRelativeDirectory)(state);
    return {
        status: 'skipped-dry-run',
        checksumJsonPath: bundleDirectory === null ? null : `${bundleDirectory}/${cli_constants_1.RELEASE_ARTIFACT_CHECKSUMS_FILENAME}`,
        checksumTextPath: bundleDirectory === null ? null : `${bundleDirectory}/${cli_constants_1.RELEASE_CHECKSUMS_FILENAME}`,
        artifacts: [],
    };
}
function createSkippedInstallerAssets(state) {
    const bundleDirectory = (0, output_lifecycle_staging_1.resolveReleaseDownloadBundleRelativeDirectory)(state);
    return {
        status: 'skipped-dry-run',
        origin: cli_constants_1.DEFAULT_RELEASE_DOWNLOAD_ORIGIN,
        assets: bundleDirectory === null
            ? []
            : [
                {
                    target: 'posix-installer',
                    filename: cli_constants_1.RELEASE_POSIX_INSTALLER_FILENAME,
                    path: `${bundleDirectory}/${cli_constants_1.RELEASE_POSIX_INSTALLER_FILENAME}`,
                    lineEndings: 'lf',
                },
                {
                    target: 'windows-installer',
                    filename: cli_constants_1.RELEASE_WINDOWS_INSTALLER_FILENAME,
                    path: `${bundleDirectory}/${cli_constants_1.RELEASE_WINDOWS_INSTALLER_FILENAME}`,
                    lineEndings: 'crlf',
                },
                {
                    target: 'posix-installer',
                    filename: cli_constants_1.RELEASE_POSIX_UNINSTALLER_FILENAME,
                    path: `${bundleDirectory}/${cli_constants_1.RELEASE_POSIX_UNINSTALLER_FILENAME}`,
                    lineEndings: 'lf',
                },
                {
                    target: 'windows-installer',
                    filename: cli_constants_1.RELEASE_WINDOWS_UNINSTALLER_FILENAME,
                    path: `${bundleDirectory}/${cli_constants_1.RELEASE_WINDOWS_UNINSTALLER_FILENAME}`,
                    lineEndings: 'crlf',
                },
            ],
    };
}
function createNotApplicableInstallerAssets() {
    return {
        status: 'not-applicable',
        origin: null,
        assets: [],
    };
}
function createNotApplicableArtifactChecksums() {
    return {
        status: 'not-applicable',
        checksumJsonPath: null,
        checksumTextPath: null,
        artifacts: [],
    };
}
function createSkippedReleaseManifest(state) {
    const bundleDirectory = (0, output_lifecycle_staging_1.resolveReleaseDownloadBundleRelativeDirectory)(state);
    return {
        status: 'skipped-dry-run',
        manifestPath: bundleDirectory === null ? null : `${bundleDirectory}/${cli_constants_1.RELEASE_MANIFEST_FILENAME}`,
        installerManifestPath: bundleDirectory === null ? null : `${bundleDirectory}/${cli_constants_1.RELEASE_INSTALLER_MANIFEST_FILENAME}`,
        releaseNotesProvenancePath: bundleDirectory === null ? null : `${bundleDirectory}/${cli_constants_1.RELEASE_NOTES_PROVENANCE_FILENAME}`,
        data: null,
    };
}
function createSkippedInstallationReadme(state) {
    const bundleDirectory = (0, output_lifecycle_staging_1.resolveReleaseDownloadBundleRelativeDirectory)(state);
    return {
        status: 'skipped-dry-run',
        path: bundleDirectory === null ? null : `${bundleDirectory}/${cli_constants_1.RELEASE_INSTALLATION_README_FILENAME}`,
    };
}
function createSkippedDownloadBundle(state) {
    return {
        status: 'skipped-dry-run',
        directory: (0, output_lifecycle_staging_1.resolveReleaseDownloadBundleRelativeDirectory)(state),
        files: [],
    };
}
function createNotApplicableInstallationReadme() {
    return {
        status: 'not-applicable',
        path: null,
    };
}
function createNotApplicableDownloadBundle() {
    return {
        status: 'not-applicable',
        directory: null,
        files: [],
    };
}
function createNotApplicableReleaseManifest() {
    return {
        status: 'not-applicable',
        manifestPath: null,
        installerManifestPath: null,
        releaseNotesProvenancePath: null,
        data: null,
    };
}
