import GraphModelMigrationNotice from "./GraphModelMigrationNotice.js";
import GraphModelMigrationRuntimeReplayRequest from "./GraphModelMigrationRuntimeReplayRequest.js";
import { requireGraphModelMigrationNonEmptyString } from "./GraphModelMigrationRequiredString.js";
import WarpError from "../errors/WarpError.js";
export const GRAPH_MODEL_MIGRATION_RUNTIME_REPLAY_PASSED = 'passed';
export const GRAPH_MODEL_MIGRATION_RUNTIME_REPLAY_FAILED = 'failed';
/** Result of replaying migrated scratch operations through normal graph runtime. */
export default class GraphModelMigrationRuntimeReplayResult {
    request;
    status;
    witness;
    replayedOperationCount;
    fatalErrors;
    constructor(fields) {
        const checkedFields = requireFields(fields);
        this.request = requireRequest(checkedFields.request);
        this.status = requireStatus(checkedFields.status);
        this.witness = requireGraphModelMigrationNonEmptyString(checkedFields.witness, 'witness');
        this.replayedOperationCount = requireNonNegativeSafeInteger(checkedFields.replayedOperationCount, 'replayedOperationCount');
        this.fatalErrors = freezeFatalNotices(checkedFields.fatalErrors);
        requireStatusMatchesFatalErrors(this.status, this.fatalErrors);
        Object.freeze(this);
    }
    /** Returns true when scratch operations were materialized by the production runtime. */
    allowsFinalization() {
        return this.status === GRAPH_MODEL_MIGRATION_RUNTIME_REPLAY_PASSED;
    }
}
function requireFields(fields) {
    if (fields === null || fields === undefined) {
        throw new WarpError('GraphModelMigrationRuntimeReplayResult fields must be provided', 'E_VALIDATION');
    }
    return fields;
}
function requireRequest(request) {
    if (!(request instanceof GraphModelMigrationRuntimeReplayRequest)) {
        throw new WarpError('request must be a GraphModelMigrationRuntimeReplayRequest', 'E_VALIDATION');
    }
    return request;
}
function requireStatus(status) {
    if (status !== GRAPH_MODEL_MIGRATION_RUNTIME_REPLAY_PASSED
        && status !== GRAPH_MODEL_MIGRATION_RUNTIME_REPLAY_FAILED) {
        throw new WarpError('runtime replay status is unsupported', 'E_VALIDATION');
    }
    return status;
}
function requireNonNegativeSafeInteger(value, name) {
    if (!Number.isSafeInteger(value) || value < 0) {
        throw new WarpError(`${name} must be a non-negative safe integer`, 'E_VALIDATION');
    }
    return value;
}
function freezeFatalNotices(fatalErrors) {
    if (!Array.isArray(fatalErrors)) {
        throw new WarpError('fatalErrors must be an array', 'E_VALIDATION');
    }
    return Object.freeze(fatalErrors.map(requireFatalNotice));
}
function requireFatalNotice(notice) {
    if (!(notice instanceof GraphModelMigrationNotice) || !notice.isFatal()) {
        throw new WarpError('fatalErrors must contain fatal migration notices', 'E_VALIDATION');
    }
    return notice;
}
function requireStatusMatchesFatalErrors(status, fatalErrors) {
    if (status === GRAPH_MODEL_MIGRATION_RUNTIME_REPLAY_PASSED && fatalErrors.length > 0) {
        throw new WarpError('passed runtime replay must not contain fatal errors', 'E_VALIDATION');
    }
    if (status === GRAPH_MODEL_MIGRATION_RUNTIME_REPLAY_FAILED && fatalErrors.length === 0) {
        throw new WarpError('failed runtime replay must contain fatal errors', 'E_VALIDATION');
    }
}
