import GraphModelMigrationLoweredPatchPlan from "./GraphModelMigrationLoweredPatchPlan.js";
import GraphModelMigrationNotice from "./GraphModelMigrationNotice.js";
import WarpError from "../errors/WarpError.js";
/** Result value for pure graph-model migration operation lowering. */
export default class GraphModelMigrationOperationLoweringResult {
    patchPlan;
    warnings;
    fatalErrors;
    constructor(fields) {
        const checkedFields = requireFields(fields);
        this.patchPlan = requireOptionalPatchPlan(checkedFields.patchPlan);
        this.warnings = freezeWarningNotices(checkedFields.warnings);
        this.fatalErrors = freezeFatalNotices(checkedFields.fatalErrors);
        requirePatchPlanMatchesFatality(this.patchPlan, this.fatalErrors);
        Object.freeze(this);
    }
    /** Returns true when lowering failed closed. */
    hasFatalErrors() {
        return this.fatalErrors.length > 0;
    }
}
function requireFields(fields) {
    if (fields === null || fields === undefined) {
        throw new WarpError('GraphModelMigrationOperationLoweringResult fields must be provided', 'E_VALIDATION');
    }
    return fields;
}
function requireOptionalPatchPlan(patchPlan) {
    if (patchPlan !== null && !(patchPlan instanceof GraphModelMigrationLoweredPatchPlan)) {
        throw new WarpError('patchPlan must be a GraphModelMigrationLoweredPatchPlan', 'E_VALIDATION');
    }
    return patchPlan;
}
function freezeWarningNotices(notices) {
    const checked = requireNoticeArray(notices, 'warnings');
    for (const notice of checked) {
        if (notice.isFatal()) {
            throw new WarpError('warnings contains the wrong notice kind', 'E_VALIDATION');
        }
    }
    return Object.freeze(checked);
}
function freezeFatalNotices(notices) {
    const checked = requireNoticeArray(notices, 'fatalErrors');
    for (const notice of checked) {
        if (!notice.isFatal()) {
            throw new WarpError('fatalErrors contains the wrong notice kind', 'E_VALIDATION');
        }
    }
    return Object.freeze(checked);
}
function requireNoticeArray(notices, label) {
    if (!Array.isArray(notices)) {
        throw new WarpError(`${label} must be an array`, 'E_VALIDATION');
    }
    return notices.map(requireNotice);
}
function requireNotice(notice) {
    if (!(notice instanceof GraphModelMigrationNotice)) {
        throw new WarpError('notices must contain GraphModelMigrationNotice instances', 'E_VALIDATION');
    }
    return notice;
}
function requirePatchPlanMatchesFatality(patchPlan, fatalErrors) {
    if (fatalErrors.length > 0 && patchPlan !== null) {
        throw new WarpError('fatal lowering results must not contain a patch plan', 'E_VALIDATION');
    }
    if (fatalErrors.length === 0 && patchPlan === null) {
        throw new WarpError('successful lowering results must contain a patch plan', 'E_VALIDATION');
    }
}
