import GraphModelMigrationArchiveRef from "./GraphModelMigrationArchiveRef.js";
import GraphModelMigrationFinalizationRequest from "./GraphModelMigrationFinalizationRequest.js";
import GraphModelMigrationFinalizationSafetyResult from "./GraphModelMigrationFinalizationSafetyResult.js";
import GraphModelMigrationNotice from "./GraphModelMigrationNotice.js";
import WarpError from "../errors/WarpError.js";
const LIVE_REF_PREFIX = 'refs/warp/';
/** Pure finalization safety gate before any live Git ref update can run. */
export default class GraphModelMigrationFinalizationSafety {
    /** Evaluates finalization preconditions without mutating Git history. */
    evaluate(request) {
        const checkedRequest = requireRequest(request);
        return new GraphModelMigrationFinalizationSafetyResult({
            request: checkedRequest,
            fatalErrors: collectFatalErrors(checkedRequest),
        });
    }
}
function collectFatalErrors(request) {
    return Object.freeze([
        validateLiveRef(request.liveRefName),
        validateConfirmation(request),
        validateGateResult(request),
        validateArchiveRef(request.archiveRefName),
        validateScratchOutput(request),
        validateRuntimeConformance(request),
        validateLiveHeadExpectation(request),
    ].filter((notice) => notice !== null));
}
function validateLiveRef(liveRefName) {
    if (liveRefName.startsWith(LIVE_REF_PREFIX)) {
        return null;
    }
    return GraphModelMigrationNotice.fatal('E_INVALID_LIVE_REF', `finalization live ref must start with ${LIVE_REF_PREFIX}`);
}
function validateConfirmation(request) {
    if (request.confirmation !== null) {
        return null;
    }
    return GraphModelMigrationNotice.fatal('E_MISSING_FINALIZATION_CONFIRMATION', 'migration finalization requires explicit operator confirmation');
}
function validateGateResult(request) {
    if (request.gateResult !== null && request.gateResult.allowsPromotion()) {
        return null;
    }
    return GraphModelMigrationNotice.fatal('E_EQUIVALENCE_GATE_NOT_PASSED', 'migration finalization requires a passed scratch equivalence gate');
}
function validateArchiveRef(archiveRefName) {
    return GraphModelMigrationArchiveRef.validateRefName(archiveRefName);
}
function validateScratchOutput(request) {
    if (request.scratchRef !== null && request.scratchHead !== null) {
        return null;
    }
    return GraphModelMigrationNotice.fatal('E_MISSING_SCRATCH_OUTPUT', 'migration finalization requires scratch ref and scratch head evidence');
}
function validateRuntimeConformance(request) {
    if (request.runtimeConformance === null || !request.runtimeConformance.allowsFinalization()) {
        return GraphModelMigrationNotice.fatal('E_RUNTIME_CONFORMANCE_NOT_PASSED', 'migration finalization requires post-migration runtime conformance evidence');
    }
    if (!runtimeConformanceMatchesScratchOutput(request)) {
        return GraphModelMigrationNotice.fatal('E_RUNTIME_CONFORMANCE_MISMATCH', 'runtime conformance evidence must match the scratch ref and head');
    }
    return null;
}
function runtimeConformanceMatchesScratchOutput(request) {
    return request.scratchRef !== null
        && request.scratchHead !== null
        && request.runtimeConformance !== null
        && request.runtimeConformance.scratchRef.refName === request.scratchRef.refName
        && request.runtimeConformance.scratchHead === request.scratchHead;
}
function validateLiveHeadExpectation(request) {
    if (request.expectedLiveHead === null) {
        return GraphModelMigrationNotice.fatal('E_MISSING_EXPECTED_LIVE_HEAD', 'migration finalization requires an expected live ref head');
    }
    if (request.observedLiveHead === null) {
        return GraphModelMigrationNotice.fatal('E_MISSING_OBSERVED_LIVE_HEAD', 'migration finalization requires observed live ref head evidence');
    }
    if (request.expectedLiveHead === request.observedLiveHead) {
        return null;
    }
    return GraphModelMigrationNotice.fatal('E_STALE_LIVE_REF_EXPECTATION', 'migration finalization live ref expectation is stale');
}
function requireRequest(request) {
    if (!(request instanceof GraphModelMigrationFinalizationRequest)) {
        throw new WarpError('request must be a GraphModelMigrationFinalizationRequest', 'E_VALIDATION');
    }
    return request;
}
