/**
 * DebugKnowledgeStore - Debug record storage
 * DD §11.3. INV-2: single writer; outbox model.
 *
 * @module packages/runtime/src/knowledge/DebugKnowledgeStore
 */

import { existsSync, mkdirSync } from 'fs'
import { join } from 'path'
import { Database } from 'bun:sqlite'

export interface DebugRecord {
  id: string
  failure_signature: string
  task_id: string
  root_cause?: string
  fix_ref?: string
  summary: string
  evidence_json?: string
  verification_json?: string
  created_at: string
  updated_at: string
  metadata_json?: string
}

export class DebugKnowledgeStore {
  private db: Database | null = null
  private db_path: string

  constructor(project_root: string) {
    this.db_path = join(project_root, '.air', 'local', 'debug-records.db')
  }

  /**
   * Open or create the debug records database.
   */
  open(): void {
    const dir = join(this.db_path, '..')
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true })

    this.db = new Database(this.db_path)
    this.db.exec('PRAGMA journal_mode = WAL')
    this.db.exec('PRAGMA synchronous = NORMAL')
    this.db.exec('PRAGMA foreign_keys = OFF')
    this.db.exec(`
      CREATE TABLE IF NOT EXISTS debug_records (
        id TEXT PRIMARY KEY,
        failure_signature TEXT NOT NULL,
        task_id TEXT NOT NULL,
        root_cause TEXT,
        fix_ref TEXT,
        summary TEXT NOT NULL,
        evidence_json TEXT,
        verification_json TEXT,
        created_at TEXT NOT NULL,
        updated_at TEXT NOT NULL,
        metadata_json TEXT
      );
      CREATE INDEX IF NOT EXISTS idx_debug_failure_signature ON debug_records(failure_signature);
      CREATE INDEX IF NOT EXISTS idx_debug_task ON debug_records(task_id);
    `)
  }

  /**
   * Insert a debug record.
   * INV-2: External write first, then emit debug.record.created via outbox.
   */
  insert(record: DebugRecord): void {
    if (!this.db) throw new Error('Store not opened')

    const stmt = this.db.prepare(`
      INSERT INTO debug_records (id, failure_signature, task_id, root_cause, fix_ref, summary, evidence_json, verification_json, created_at, updated_at, metadata_json)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `)
    stmt.run(record.id, record.failure_signature, record.task_id, record.root_cause, record.fix_ref, record.summary, record.evidence_json, record.verification_json, record.created_at, record.updated_at, record.metadata_json)
  }

  /**
   * Look up records by failure signature.
   */
  lookup_by_signature(failure_signature: string): DebugRecord[] {
    if (!this.db) return []
    const stmt = this.db.prepare('SELECT * FROM debug_records WHERE failure_signature = ? ORDER BY created_at DESC')
    return stmt.all(failure_signature) as DebugRecord[]
  }

  /**
   * Look up records by task ID.
   */
  lookup_by_task(task_id: string): DebugRecord[] {
    if (!this.db) return []
    const stmt = this.db.prepare('SELECT * FROM debug_records WHERE task_id = ?')
    return stmt.all(task_id) as DebugRecord[]
  }

  /**
   * Update record fields.
   */
  update(id: string, patch: { root_cause?: string; fix_ref?: string; summary?: string; updated_at?: string }): void {
    if (!this.db) return
    const fields: string[] = []
    const values: unknown[] = []
    for (const [k, v] of Object.entries(patch)) {
      if (v !== undefined) { fields.push(`${k} = ?`); values.push(v) }
    }
    if (fields.length === 0) return
    values.push(id)
    this.db.prepare(`UPDATE debug_records SET ${fields.join(', ')} WHERE id = ?`).run(...values)
  }
}
