// src/core/security/IAuditService.ts

import type {
  IAuditEvent,
  IAuditEventSummary,
  AuditAction,
  AuditOutcome,
} from './IAuditEvent';
import type { AuditLevel } from './ISupervisorSecurityPolicy';
import type { ICapabilityToken } from './ICapabilityToken';

/**
 * Audit Service Interface - Records and queries security events.
 *
 * Vision 27 Section 7: "All security-relevant events MUST be auditable"
 *
 * Expert consensus:
 * - Pluggable implementation (in-memory for dev, SIEM for prod)
 * - Configurable audit level per realm
 * - Query support for compliance reporting
 *
 * See: Vision/27-SECURITY-FEDERATION-DRAFT.md Section 7
 */

// ═══════════════════════════════════════════════════════════════════════════
// AUDIT RECORD INPUT
// ═══════════════════════════════════════════════════════════════════════════

/**
 * Input for recording an audit event.
 * All required fields; optional fields computed by service.
 */
export interface IAuditRecordInput {
  /** Who initiated */
  principal: string;

  /** Capability used (if any) */
  capability?: ICapabilityToken;

  /** Action performed */
  action: AuditAction;

  /** Target mount path */
  target: string;

  /** Specific command (for 'invoke') */
  command?: string;

  /** Source realm */
  sourceRealm: string;

  /** Target realm */
  targetRealm: string;

  /** Outcome */
  outcome: AuditOutcome;

  /** Denial reason (if denied) */
  denialReason?: string;

  /** Error details (if error) */
  errorDetails?: string;
}

// ═══════════════════════════════════════════════════════════════════════════
// AUDIT QUERY
// ═══════════════════════════════════════════════════════════════════════════

/**
 * Query parameters for audit trail.
 *
 * Vision 27 Section 7.2 compliance queries:
 * - WHO ACCESSED WHAT
 * - WHAT DID USER X DO
 * - CAPABILITY LINEAGE
 * - ANOMALY DETECTION
 */
export interface IAuditQuery {
  /** Filter by principal */
  principal?: string;

  /** Filter by target pattern (supports wildcards) */
  targetPattern?: string;

  /** Filter by action types */
  actions?: AuditAction[];

  /** Filter by outcome */
  outcome?: AuditOutcome;

  /** Filter by source realm */
  sourceRealm?: string;

  /** Filter by target realm */
  targetRealm?: string;

  /** Time range start (ms since epoch) */
  fromTimestamp?: number;

  /** Time range end (ms since epoch) */
  toTimestamp?: number;

  /** Maximum results */
  limit?: number;

  /** Skip first N results (pagination) */
  offset?: number;
}

/**
 * Result of an audit query.
 */
export interface IAuditQueryResult {
  /** Matching events */
  events: IAuditEvent[];

  /** Total count (for pagination) */
  totalCount: number;

  /** Whether more results exist */
  hasMore: boolean;
}

// ═══════════════════════════════════════════════════════════════════════════
// AUDIT SERVICE INTERFACE
// ═══════════════════════════════════════════════════════════════════════════

/**
 * Audit service - records and queries security events.
 *
 * Implementations:
 * - InMemoryAuditService - Development/testing
 * - ConsoleAuditService - Simple logging
 * - SIEMAuditService - Enterprise SIEM integration (Phase 3+)
 *
 * Vision 27 Section 7.3:
 * - 'none': No logging
 * - 'failures': Only denied/error outcomes
 * - 'summary': Basic info (who, what, target, outcome)
 * - 'full': Complete event details
 */
export interface IAuditService {
  /**
   * Record an audit event.
   *
   * @param input - Event details
   * @param level - Audit level (determines detail captured)
   * @returns Event ID (for correlation)
   */
  record(input: IAuditRecordInput, level: AuditLevel): string;

  /**
   * Query audit trail.
   *
   * @param query - Query parameters
   * @returns Matching events
   */
  query(query: IAuditQuery): IAuditQueryResult;

  /**
   * Get capability delegation chain.
   *
   * Vision 27 Section 7.2: "CAPABILITY LINEAGE"
   * Query: "How did external-contractor get access to /eng/secrets?"
   *
   * @param capabilityId - Capability to trace
   * @returns Chain of delegation events
   */
  getCapabilityLineage(capabilityId: string): IAuditEvent[];

  /**
   * Get event count by outcome (for dashboards).
   *
   * @param fromTimestamp - Start time
   * @param toTimestamp - End time
   */
  getOutcomeStats(fromTimestamp?: number, toTimestamp?: number): {
    success: number;
    denied: number;
    error: number;
  };

  /**
   * Export audit trail for compliance.
   *
   * Vision 27 Section 7.2:
   * - SOC2: Access control enforcement proof
   * - GDPR: Right to access data
   *
   * @param query - What to export
   * @returns Array of full or summary events
   */
  export(query: IAuditQuery): IAuditEvent[] | IAuditEventSummary[];

  /**
   * Clear old events (per retention policy).
   *
   * @param olderThan - Clear events before this timestamp
   * @returns Number of events cleared
   */
  clearOlderThan(olderThan: number): number;
}

// ═══════════════════════════════════════════════════════════════════════════
// SECURITY-CRITICAL ACTIONS (always audit at 100%)
// ═══════════════════════════════════════════════════════════════════════════

/**
 * Actions that are ALWAYS audited regardless of audit level.
 *
 * Vision 27 Section 7.3:
 * | Event Type | Policy | Rationale |
 * |------------|--------|-----------|
 * | Context creation | **Always audit** | Security-critical |
 * | Spawn operations | **Always audit** | Creates persistent actors |
 * | Interpreter events | **Always audit** | Code execution boundary |
 * | All failures/denials | **Always audit** | Security incidents |
 */
export const SECURITY_CRITICAL_ACTIONS: AuditAction[] = [
  'spawn',
  'context-create',
  'interpreter',
  'capability-mint',
  'capability-revoke',
];

/**
 * Check if an action is security-critical (always audit).
 */
export function isSecurityCriticalAction(action: AuditAction): boolean {
  return SECURITY_CRITICAL_ACTIONS.includes(action);
}

/**
 * Check if outcome should always be audited.
 * All failures/denials are always logged.
 */
export function shouldAlwaysAudit(
  action: AuditAction,
  outcome: AuditOutcome
): boolean {
  // Always audit security-critical actions
  if (isSecurityCriticalAction(action)) {
    return true;
  }

  // Always audit failures/denials
  if (outcome === 'denied' || outcome === 'error') {
    return true;
  }

  return false;
}
