import PatchError from "../errors/PatchError.js";
import { OP_TYPES } from "../types/TickReceipt.js";
const REQUIRED_STRATEGY_METHODS = Object.freeze([
    'validate',
    'mutate',
    'outcome',
    'snapshot',
    'accumulate',
]);
const VALID_RECEIPT_OPS = new Set(OP_TYPES);
export function validateOpStrategyRegistry(registry, validReceiptOps = VALID_RECEIPT_OPS) {
    for (const [opType, strategy] of registry) {
        const checkedStrategy = requireStrategyObject(opType, strategy);
        for (const methodName of REQUIRED_STRATEGY_METHODS) {
            requireStrategyMethod(opType, checkedStrategy, methodName);
        }
        const receiptName = requireReceiptName(opType, checkedStrategy);
        if (!validReceiptOps.has(receiptName)) {
            throw new PatchError(`OpStrategy '${opType}' receiptName '${receiptName}' is not in TickReceipt OP_TYPES`, { context: { opType, receiptName } });
        }
    }
}
function requireStrategyObject(opType, strategy) {
    if (strategy !== null && strategy !== undefined && typeof strategy === 'object') {
        return strategy;
    }
    throw new PatchError(`OpStrategy '${opType}' must be an object`, { context: { opType } });
}
function requireStrategyMethod(opType, strategy, methodName) {
    if (typeof strategy[methodName] === 'function') {
        return;
    }
    throw new PatchError(`OpStrategy '${opType}' is missing method '${methodName}'`, { context: { opType, methodName } });
}
function requireReceiptName(opType, strategy) {
    if (typeof strategy.receiptName === 'string' && strategy.receiptName.length > 0) {
        return strategy.receiptName;
    }
    throw new PatchError(`OpStrategy '${opType}' is missing receiptName`, { context: { opType } });
}
