import { PlatformError } from './errors.mjs';

const POLICY_ID = /^[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)+$/;

export class PolicyEngine {
  #policies = new Map();

  register(id, evaluator, { owner = 'vendoo.security', description = '' } = {}) {
    const normalized = String(id || '');
    if (!POLICY_ID.test(normalized)) throw new PlatformError(`Ungültige Policy-ID: ${normalized}`, { code: 'POLICY_ID_INVALID' });
    if (this.#policies.has(normalized)) throw new PlatformError(`Policy bereits registriert: ${normalized}`, { code: 'POLICY_DUPLICATE' });
    if (typeof evaluator !== 'function') throw new PlatformError(`Policy benötigt eine Prüffunktion: ${normalized}`, { code: 'POLICY_EVALUATOR_INVALID' });
    this.#policies.set(normalized, { id: normalized, evaluator, owner, description });
  }

  async evaluate(id, context) {
    const policy = this.#policies.get(id);
    if (!policy) {
      return { allowed: false, reason: 'policy_not_registered', policy: id };
    }
    const result = await policy.evaluator(Object.freeze({ ...context }));
    if (result === true) return { allowed: true, policy: id };
    if (result === false || result == null) return { allowed: false, reason: 'denied', policy: id };
    return { allowed: Boolean(result.allowed), reason: result.reason || null, policy: id, details: result.details || null };
  }

  list() {
    return [...this.#policies.values()].map(({ evaluator: _evaluator, ...policy }) => ({ ...policy }));
  }
}
