import QueryError from "../../errors/QueryError.js";
const EXACT_ENTITY_SUPPORT_RULE = 'exact-entity';
const NEIGHBORHOOD_SUPPORT_RULE = 'neighborhood';
const TRAVERSAL_WINDOW_SUPPORT_RULE = 'traversal-window';
const GLOBAL_DISCOVERY_REFUSED_SUPPORT_RULE = 'global-discovery-refused';
export const OPTIC_SUPPORT_RULES = Object.freeze([
    EXACT_ENTITY_SUPPORT_RULE,
    NEIGHBORHOOD_SUPPORT_RULE,
    TRAVERSAL_WINDOW_SUPPORT_RULE,
    GLOBAL_DISCOVERY_REFUSED_SUPPORT_RULE,
]);
export default class OpticSupportRule {
    value;
    constructor(value) {
        this.value = requireOpticSupportRuleValue(value);
        Object.freeze(this);
    }
    static exactEntity() {
        return new OpticSupportRule(EXACT_ENTITY_SUPPORT_RULE);
    }
    static neighborhood() {
        return new OpticSupportRule(NEIGHBORHOOD_SUPPORT_RULE);
    }
    static traversalWindow() {
        return new OpticSupportRule(TRAVERSAL_WINDOW_SUPPORT_RULE);
    }
    static globalDiscoveryRefused() {
        return new OpticSupportRule(GLOBAL_DISCOVERY_REFUSED_SUPPORT_RULE);
    }
    isExactEntity() {
        return this.value === EXACT_ENTITY_SUPPORT_RULE;
    }
    isNeighborhood() {
        return this.value === NEIGHBORHOOD_SUPPORT_RULE;
    }
    isTraversalWindow() {
        return this.value === TRAVERSAL_WINDOW_SUPPORT_RULE;
    }
    refusesGlobalDiscovery() {
        return this.value === GLOBAL_DISCOVERY_REFUSED_SUPPORT_RULE;
    }
    equals(other) {
        return this.value === other.value;
    }
    toString() {
        return this.value;
    }
}
export function requireOpticSupportRuleValue(value) {
    if (typeof value !== 'string') {
        throwOpticSupportRuleError();
    }
    const valid = OPTIC_SUPPORT_RULES.find((candidate) => candidate === value);
    if (valid === undefined) {
        throwOpticSupportRuleError();
    }
    return valid;
}
function throwOpticSupportRuleError() {
    throw new QueryError('Optic support rule is invalid.', {
        code: 'E_OPTIC_SCHEMA',
        context: { field: 'supportRule' },
    });
}
