"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cutoverRepositoryMigrationSync = cutoverRepositoryMigrationSync;
const workspace_migration_application_1 = require("../workspace-migration-application");
const workspace_migration_planning_1 = require("../workspace-migration-planning");
const contracts_1 = require("./contracts");
const filesystem_1 = require("./filesystem");
const mapping_1 = require("./mapping");
const preservation_1 = require("./preservation");
const rehearsal_1 = require("./rehearsal");
const validation_1 = require("./validation");
/**
 * Consume one exact, current rehearsal report as authorization for the active
 * repository migration.
 *
 * Every report, source, mapping, build, guard, plan, destination, revision,
 * and live-lock check completes before the shared migration transaction is
 * allowed to mutate canonical state. An incomplete transaction remains
 * incomplete and retains its durable recovery evidence.
 */
function cutoverRepositoryMigrationSync(options) {
    const repositoryRoot = (0, filesystem_1.resolveCanonicalRepositoryRoot)(options.repositoryRoot);
    const expectedReportDigest = (0, validation_1.requireCutoverDigest)(options.expectedReportDigest);
    const report = (0, validation_1.readRepositoryMigrationRehearsalReportSync)(repositoryRoot);
    if (report.reportDigest !== expectedReportDigest) {
        throw new contracts_1.RepositoryMigrationRehearsalError("cutover-stale", `Canonical cutover expected rehearsal report '${expectedReportDigest}', but the tracked report is '${report.reportDigest}'. No write was attempted.`);
    }
    if (report.verdict !== "accepted"
        || report.cutoverDisposition.readyForMilestone06Apply !== true
        || report.cutoverDisposition.blockingGapIds.length > 0
        || report.plan.status !== "ready"
        || report.plan.findingCount !== 0
        || report.preservation.verdict !== "accepted"
        || report.explicitGaps.some((gap) => gap.classification === "cutover-blocker")
        || report.validationReceipts.some((receipt) => !receipt.accepted)) {
        throw new contracts_1.RepositoryMigrationRehearsalError("cutover-blocked", "The exact rehearsal report is not an accepted, blocker-free Milestone 06 cutover authorization. No write was attempted.");
    }
    (0, validation_1.rejectLiveRepositoryWriteLock)(repositoryRoot);
    const verification = (0, rehearsal_1.verifyRepositoryMigrationRehearsalSync)({ repositoryRoot });
    if (verification.verdict !== "accepted"
        || verification.reportDigest !== expectedReportDigest) {
        throw new contracts_1.RepositoryMigrationRehearsalError("cutover-stale", `The exact rehearsal report is no longer current: ${verification.reasons.join(" ") || "verification did not accept the requested report digest"}. No write was attempted.`);
    }
    const sourceManifest = (0, preservation_1.createRepositoryPlanningManifestSync)(repositoryRoot);
    const mappingInventory = (0, preservation_1.createRepositoryMigrationMappingInventorySync)(repositoryRoot);
    const mapping = (0, mapping_1.readRepositoryMigrationMappingDocumentSync)(repositoryRoot, {
        sourceManifest,
        mappingInventory
    });
    const migrationBuildIdentity = (0, filesystem_1.readVolatileEvidence)(repositoryRoot).migrationBuildIdentity;
    const canonicalGuard = (0, preservation_1.computeRepositoryMigrationCanonicalGuardSync)(repositoryRoot);
    const selections = (0, validation_1.mappingSelections)(mapping);
    const plan = (0, workspace_migration_planning_1.planWorkspaceStructureMigrationSync)({
        repositoryRoot,
        selections
    });
    const authorizationReasons = [
        sourceManifest.aggregateDigest === report.authorization.sourceManifestDigest
            && report.source.manifestDigest === report.authorization.sourceManifestDigest
            ? null
            : "source manifest",
        mapping.mappingDigest === report.authorization.mappingDigest
            && report.mapping.digest === report.authorization.mappingDigest
            && mapping.selections.length === report.mapping.selectionCount
            ? null
            : "mapping",
        migrationBuildIdentity === report.authorization.migrationBuildIdentity
            && report.migrationBuildIdentity === report.authorization.migrationBuildIdentity
            ? null
            : "migration build identity",
        canonicalGuard.aggregateDigest === report.canonicalGuards[0]?.aggregateDigest
            && report.canonicalGuards.every((guard) => guard.matchedInitial)
            ? null
            : "canonical guard",
        plan.planDigest === report.authorization.planDigest
            && report.plan.digest === report.authorization.planDigest
            && plan.status === "ready"
            && plan.findings.length === 0
            ? null
            : "active migration plan"
    ].filter((reason) => reason !== null);
    if (authorizationReasons.length > 0) {
        throw new contracts_1.RepositoryMigrationRehearsalError("cutover-stale", `Canonical cutover authorization drifted in: ${authorizationReasons.join(", ")}. No write was attempted.`);
    }
    (0, validation_1.rejectLiveRepositoryWriteLock)(repositoryRoot);
    let application;
    try {
        application = (0, workspace_migration_application_1.applyWorkspaceStructureMigrationSync)({
            repositoryRoot,
            selections,
            expectedPlanDigest: plan.planDigest,
            actor: options.actor ?? "phase-07-milestone-06-cutover",
            reason: options.reason
                ?? "Apply the exact just-in-time rehearsal-authorized canonical planning cutover.",
            appliedAt: options.appliedAt,
            transaction: options.transaction
        });
    }
    catch (error) {
        if (error instanceof workspace_migration_application_1.WorkspaceMigrationApplicationError) {
            throw new contracts_1.RepositoryMigrationRehearsalError("cutover-stale", error.message);
        }
        throw error;
    }
    if (application.outcome === "committed" && application.writeApplied) {
        (0, validation_1.removeEmptyNumericPlanningRootsSync)(repositoryRoot);
    }
    const remainingNumericRootPaths = (0, validation_1.activeNumericPlanningRootPaths)(repositoryRoot);
    const committed = application.outcome === "committed"
        && application.writeApplied
        && remainingNumericRootPaths.length === 0;
    return {
        protocolVersion: contracts_1.REPOSITORY_MIGRATION_REHEARSAL_PROTOCOL_VERSION,
        operation: "cutover",
        expectedReportDigest,
        reportDigest: report.reportDigest,
        verification,
        authorization: {
            sourceManifestDigest: sourceManifest.aggregateDigest,
            mappingDigest: mapping.mappingDigest,
            migrationBuildIdentity,
            canonicalGuardDigest: canonicalGuard.aggregateDigest,
            planDigest: plan.planDigest
        },
        application,
        committed,
        durableMigrationRecordPath: application.migrationRecordPath,
        remainingNumericRootPaths,
        nextAction: committed
            ? `Resolve every post-cutover planning path from '${application.migrationRecordPath}'; do not reuse numbered source paths.`
            : application.nextAction
    };
}
