/**
 * IRecordStore — interface for the unified interaction store.
 *
 * Implementations:
 *   SqliteRecordStore  (daemon, better-sqlite3)
 *   InMemoryRecordBuffer (browser, ring buffer — future)
 *
 * See: ARCHITECTURE/ARCHITECTURE-OBSERVABILITY-PIPELINE-V2.md §4-5
 */

import type { InteractionRecord, RecordKind, RecordPhase, RecordChannel } from './InteractionRecord';

// ── Query Filter ─────────────────────────────────────────────────────────────

export interface RecordFilter {
  /** Filter by record kind(s). */
  kind?: RecordKind[];
  /** Filter by phase(s). */
  phase?: RecordPhase[];
  /** Filter by source mount (exact match). */
  source?: string;
  /** Filter by source prefix (subtree query, e.g., 'code.files'). */
  parentMount?: string;
  /** Filter by trace ID. */
  traceId?: string;
  /** Filter by session ID. */
  sessionId?: string;
  /** Filter by browser resume ID. */
  resumeId?: string;
  /** Filter by request ID. */
  requestId?: string;
  /** Filter by session group. */
  sessionGroup?: string;
  /** Filter by principal owner/caller. */
  principalId?: string;
  /** Filter by target mount. */
  target?: string;
  /** Filter by root. */
  root?: string;
  /** Filter by base root (cross-tab). */
  baseRoot?: string;
  /** Filter by channel. */
  channel?: RecordChannel;
  /** Filter by operation name. */
  op?: string;
  /** Filter by message role. */
  role?: 'user' | 'assistant' | 'tool';
  /** Filter by model ID. */
  modelId?: string;
  /** Time range filter. */
  timeRange?: { from?: number; to?: number };
  /** Max results. */
  limit?: number;
  /** Offset for pagination. */
  offset?: number;
  /** Sort order (default: ts ASC). 'id' = insertion order. */
  orderBy?: 'ts' | 'duration_ms' | 'seq' | 'id';
  /** Sort direction (default: 'asc'). */
  orderDir?: 'asc' | 'desc';
}

// ── Retention Policy ─────────────────────────────────────────────────────────

export interface RetentionPolicy {
  /** Default max age in ms. Records older than this are pruned. */
  maxAgeMs: number;
  /** Per-kind overrides. Use Infinity to keep forever. */
  kindOverrides?: Partial<Record<RecordKind, number>>;
}

// ── IRecordStore ─────────────────────────────────────────────────────────────

export interface IRecordStore {
  /**
   * Write one or more records to the store.
   * Records are assigned auto-increment IDs.
   */
  write(records: InteractionRecord | InteractionRecord[]): void;

  /**
   * Query records matching the filter.
   * Returns records sorted by (ts, seq) ascending by default.
   */
  query(filter: RecordFilter): InteractionRecord[];

  /**
   * Get all records for a trace (by traceId), ordered by ts.
   * Convenience for query({ traceId }).
   */
  getTrace(traceId: string): InteractionRecord[];

  /**
   * Get conversation thread for a session (messages + tool calls).
   * Returns records with kind in ['message', 'tool-call'], ordered by ts.
   */
  getThread(sessionId: string, opts?: { limit?: number }): InteractionRecord[];

  /**
   * Get all records for a single request (one oracle loop).
   */
  getRequest(requestId: string): InteractionRecord[];

  /**
   * Get the latest state record for a source mount.
   */
  getLatestState(source: string, opts?: {
    sessionId?: string;
    before?: number;
    op?: string;
  }): InteractionRecord | undefined;

  /**
   * Full-text search across record text content.
   * Requires FTS5 (Phase 5). Returns empty array if not available.
   */
  search(text: string, filter?: RecordFilter): InteractionRecord[];

  /**
   * Delete records older than the retention policy allows.
   * Per-kind overrides enable keeping domain content longer than infra metrics.
   */
  prune(policy: RetentionPolicy): number;

  /**
   * Total record count (for diagnostics).
   */
  count(filter?: RecordFilter): number;

  /**
   * Close the store and release resources.
   */
  close(): void;
}
