import MemoryBudgetError from "../errors/MemoryBudgetError.js";
import MemoryCapability from "./MemoryCapability.js";
/** Immutable queryable report for bounded, transitional, diagnostic, and legacy memory surfaces. */
export default class MemoryCapabilityReport {
    capabilities;
    constructor(fields) {
        this.capabilities = freezeCapabilities(requireReportFields(fields).capabilities);
        Object.freeze(this);
    }
    requireCapability(name) {
        const capability = this.capabilities.find((candidate) => candidate.name === name);
        if (capability !== undefined) {
            return capability;
        }
        throw new MemoryBudgetError('Memory capability report is missing a requested capability', {
            code: 'E_MEMORY_CAPABILITY_MISSING',
            context: { name },
        });
    }
    safeNames() {
        return this.namesMatching((capability) => capability.posture.isSafe());
    }
    transitionalNames() {
        return this.namesMatching((capability) => capability.posture.isTransitional());
    }
    diagnosticNames() {
        return this.namesMatching((capability) => capability.posture.isDiagnostic());
    }
    legacyNames() {
        return this.namesMatching((capability) => capability.posture.isLegacy());
    }
    namesMatching(predicate) {
        return Object.freeze(this.capabilities.filter(predicate).map((capability) => capability.name));
    }
}
function requireReportFields(fields) {
    if (fields !== null && typeof fields === 'object') {
        return fields;
    }
    throw new MemoryBudgetError('MemoryCapabilityReport requires object fields', {
        code: 'E_MEMORY_CAPABILITY_INVALID',
        context: { field: 'fields' },
    });
}
function freezeCapabilities(values) {
    if (!Array.isArray(values) || values.length === 0) {
        throw new MemoryBudgetError('Memory capability report requires at least one capability', {
            code: 'E_MEMORY_CAPABILITY_INVALID',
            context: { field: 'capabilities' },
        });
    }
    const names = new Set();
    const capabilities = [];
    for (const value of values) {
        const capability = requireCapability(value);
        requireUniqueName(names, capability.name);
        capabilities.push(capability);
    }
    return Object.freeze(capabilities);
}
function requireCapability(value) {
    if (value instanceof MemoryCapability) {
        return value;
    }
    throw new MemoryBudgetError('Memory capability report entries must be MemoryCapability values', {
        code: 'E_MEMORY_CAPABILITY_INVALID',
        context: { field: 'capabilities' },
    });
}
function requireUniqueName(names, name) {
    if (!names.has(name)) {
        names.add(name);
        return;
    }
    throw new MemoryBudgetError('Memory capability names must be unique', {
        code: 'E_MEMORY_CAPABILITY_INVALID',
        context: { field: 'name', value: name },
    });
}
