// src/core/security/ITopicClaimRegistry.ts

import type {
  ITopicClaim,
  IClaimResult,
  IClaimOptions,
  IClaimQuery,
} from './ITopicClaim';

/**
 * Configuration options for TopicClaimRegistry.
 *
 * Butler Lampson (Turing Award, Capability Systems):
 *   "Security policies must be explicit and configurable.
 *    Open vs closed namespaces are both valid - the choice depends on the use case."
 */
export interface ITopicClaimRegistryConfig {
  /**
   * Strict mode - when true, unclaimed territory is forbidden.
   *
   * - false (default): Open territory - operations on unclaimed prefixes are allowed
   * - true: Closed territory - all operations require an explicit claim
   *
   * Mark Miller (Capability Security, E Language):
   *   "In capability systems, explicit > implicit. Strict mode makes authority explicit."
   *
   * @default false
   */
  strictMode?: boolean;
}

/**
 * Topic Claim Registry - manages namespace authority in the supervision tree.
 *
 * Vision 27 §1.5 (Separator Semantics):
 * - Components claim PREFIXES (not single topics)
 * - Prefix 'flowpad.tree' owns everything under 'flowpad.tree.*'
 * - DOT (.) = supervision boundary, SLASH (/) = transport boundary
 *
 * Carl Hewitt (Actor Model):
 *   "Every actor has a unique address. The registry ensures no collisions."
 *
 * Joe Armstrong (Erlang, "Programming Erlang"):
 *   "Process registration is essential - it prevents confusion attacks
 *    and enables the 'let it crash' philosophy by knowing who owns what."
 *
 * Mark Miller (Capability Security, E Language):
 *   "The registry is itself a capability. Only holders can claim prefixes."
 *
 * Butler Lampson (Turing Award, Capability Systems):
 *   "Registry is the root of trust. All authority flows from registration."
 *
 * Usage:
 * ```typescript
 * const registry = new TopicClaimRegistry();
 *
 * // Parent claims root prefix
 * const parentClaim = registry.claim('flowpad', 'flowpad');
 *
 * // Parent delegates child prefix
 * const childClaim = registry.claim(
 *   'flowpad.tree',
 *   'flowpad/tree',
 *   { delegatedBy: 'flowpad' }
 * );
 *
 * // Verify authority
 * if (registry.canCreate('flowpad.tree.node', 'flowpad/tree')) {
 *   // Child can create under its claimed prefix
 * }
 * ```
 */
export interface ITopicClaimRegistry {
  /**
   * Claim authority over a topic prefix.
   *
   * Vision 27 Delegation Model:
   * - Root claims (no delegatedBy) establish new authority
   * - Delegated claims must be authorized by parent's existing claim
   *
   * @param prefix - The topic prefix to claim (e.g., 'flowpad.tree')
   * @param owner - Mount path of the claiming component
   * @param options - Claim options including capabilities and delegation
   * @returns Claim result with success status and claim or error
   *
   * @example Root claim
   * ```typescript
   * registry.claim('flowpad', 'flowpad');
   * ```
   *
   * @example Delegated claim
   * ```typescript
   * registry.claim('flowpad.tree', 'flowpad/tree', {
   *   delegatedBy: 'flowpad'
   * });
   * ```
   */
  claim(
    prefix: string,
    owner: string,
    options?: IClaimOptions & { delegatedBy?: string }
  ): IClaimResult;

  /**
   * Release a topic claim.
   *
   * Joe Armstrong: "When a process dies, its registrations must be cleaned up.
   * This prevents zombie names that point to nothing."
   *
   * @param prefix - The prefix to release
   * @param owner - The owner releasing the claim (must match original claimer)
   * @param reason - Reason for release (for audit trail)
   * @returns true if released, false if not found or not owned
   */
  release(prefix: string, owner: string, reason?: string): boolean;

  /**
   * Check if a component can create/operate at a given topic.
   *
   * Authorization rules (Vision 27 §4.2):
   * 1. Owner of exact prefix can operate
   * 2. Owner of ancestor prefix can operate (parent authority)
   * 3. Delegated authority flows to children
   *
   * @param topic - The full topic to check (e.g., 'flowpad.tree.node')
   * @param owner - The component attempting the operation
   * @returns true if authorized, false otherwise
   *
   * @example
   * ```typescript
   * // If 'flowpad' owns 'flowpad'
   * registry.canCreate('flowpad.tree.node', 'flowpad'); // true
   * registry.canCreate('other.tree', 'flowpad'); // false
   * ```
   */
  canCreate(topic: string, owner: string): boolean;

  /**
   * Check if a component can operate on a topic with specific capability.
   *
   * @param topic - The topic to check
   * @param owner - The component attempting the operation
   * @param capability - The specific capability required ('read', 'write', etc.)
   * @returns true if the owner has the capability on the topic
   */
  canOperate(topic: string, owner: string, capability: string): boolean;

  /**
   * Get the claim for a specific prefix (exact match).
   *
   * @param prefix - The prefix to look up
   * @returns The claim if found, undefined otherwise
   */
  getClaim(prefix: string): ITopicClaim | undefined;

  /**
   * Get the authoritative claim for a topic (finds covering prefix).
   *
   * This finds the MOST SPECIFIC claim that covers the topic.
   * For 'flowpad.tree.node', it might return:
   * - 'flowpad.tree' claim (if exists)
   * - 'flowpad' claim (if no more specific claim)
   *
   * @param topic - The topic to find authority for
   * @returns The covering claim, or undefined if unclaimed territory
   */
  getAuthority(topic: string): ITopicClaim | undefined;

  /**
   * Get all claims owned by a component.
   *
   * @param owner - The component mount path
   * @returns Array of claims owned by this component
   */
  getClaimsByOwner(owner: string): ITopicClaim[];

  /**
   * Get all claims matching a query.
   *
   * @param query - Query options for filtering claims
   * @returns Array of matching claims
   */
  query(query: IClaimQuery): ITopicClaim[];

  /**
   * Get all active (non-revoked) claims.
   *
   * @returns Array of all active claims
   */
  getAllClaims(): ITopicClaim[];

  /**
   * Revoke all claims owned by a component.
   *
   * Called when a component is destroyed.
   * Also recursively revokes all claims delegated by this component.
   *
   * Joe Armstrong: "When the supervisor dies, all its children must be notified.
   * In our case, their claims become invalid."
   *
   * @param owner - The component being destroyed
   * @param reason - Reason for revocation (e.g., 'component_destroyed')
   * @returns Number of claims revoked
   */
  revokeAll(owner: string, reason?: string): number;

  /**
   * Check if a topic falls under any claimed prefix.
   *
   * @param topic - The topic to check
   * @returns true if the topic is under a claimed prefix
   */
  isUnderAuthority(topic: string): boolean;

  /**
   * Clear all claims (for testing purposes).
   *
   * WARNING: Only use in tests. In production, use revokeAll per component.
   */
  clear(): void;
}
