import Database from 'better-sqlite3';
import * as fs from 'fs';
import * as path from 'path';
import { s as shooterDataDir } from './shooter-home-4f_HkdGI.js';

const MAX_AGE_MS = 5 * 60 * 1e3;
const DB_DIR = shooterDataDir();
const DB_PATH = path.join(DB_DIR, "shooter.db");
class PendingRequestsStore {
  db;
  constructor() {
    fs.mkdirSync(DB_DIR, { recursive: true });
    this.db = new Database(DB_PATH);
    this.db.pragma("journal_mode = WAL");
    this.db.exec(`
      CREATE TABLE IF NOT EXISTS pending_requests (
        request_id    TEXT PRIMARY KEY,
        session_id    TEXT NOT NULL,
        tool_name     TEXT NOT NULL,
        tool_input    TEXT NOT NULL DEFAULT '{}',
        decision      TEXT,
        created_at    INTEGER NOT NULL,
        decided_at    INTEGER,
        question      TEXT,
        options       TEXT NOT NULL DEFAULT '[]',
        response_kind TEXT NOT NULL DEFAULT 'hook'
      )
    `);
    this.migrate();
  }
  cleanup(maxAgeMs) {
    const cutoff = Date.now() - maxAgeMs;
    const result = this.db.prepare("DELETE FROM pending_requests WHERE created_at < ?").run(cutoff);
    return result.changes;
  }
  delete(requestId) {
    this.db.prepare("DELETE FROM pending_requests WHERE request_id = ?").run(requestId);
  }
  get(requestId) {
    const row = this.db.prepare("SELECT * FROM pending_requests WHERE request_id = ?").get(requestId);
    return row ? rowToRecord(row) : null;
  }
  getRich(requestId) {
    const row = this.db.prepare("SELECT * FROM pending_requests WHERE request_id = ?").get(requestId);
    return row ? rowToRich(row) : null;
  }
  insert(requestId, data) {
    this.db.prepare(
      `INSERT OR REPLACE INTO pending_requests
         (request_id, session_id, tool_name, tool_input, decision, created_at, decided_at, question, options, response_kind)
         VALUES (?, ?, ?, ?, NULL, ?, NULL, ?, ?, ?)`
    ).run(
      requestId,
      data.sessionId,
      data.toolName,
      JSON.stringify(data.toolInput),
      Date.now(),
      data.question ?? null,
      JSON.stringify(data.options ?? []),
      data.responseKind ?? "hook"
    );
  }
  setDecision(requestId, decision) {
    const result = this.db.prepare("UPDATE pending_requests SET decision = ?, decided_at = ? WHERE request_id = ?").run(decision, Date.now(), requestId);
    return result.changes > 0;
  }
  /**
   * Add columns introduced in later versions. Idempotent — uses
   * PRAGMA table_info to check before each ALTER TABLE so re-running
   * against a fully-migrated DB is a no-op.
   */
  migrate() {
    const cols = this.db.prepare("PRAGMA table_info(pending_requests)").all();
    const existing = new Set(cols.map((c) => c.name));
    const wanted = [
      { name: "question", sql: "ALTER TABLE pending_requests ADD COLUMN question TEXT" },
      {
        name: "options",
        sql: "ALTER TABLE pending_requests ADD COLUMN options TEXT NOT NULL DEFAULT '[]'"
      },
      {
        name: "response_kind",
        sql: "ALTER TABLE pending_requests ADD COLUMN response_kind TEXT NOT NULL DEFAULT 'hook'"
      }
    ];
    for (const col of wanted) {
      if (!existing.has(col.name)) {
        this.db.exec(col.sql);
      }
    }
  }
}
function parseOptions(raw) {
  if (typeof raw !== "string" || raw.length === 0) {
    return [];
  }
  try {
    const parsed = JSON.parse(raw);
    if (Array.isArray(parsed)) {
      return parsed;
    }
  } catch {
  }
  return [];
}
function parseToolInput(raw) {
  if (typeof raw !== "string" || raw.length === 0) {
    return {};
  }
  try {
    const parsed = JSON.parse(raw);
    if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
      return parsed;
    }
  } catch {
  }
  return {};
}
function rowToRecord(row) {
  const decision = row.decision;
  return {
    createdAt: row.created_at,
    decidedAt: row.decided_at ?? null,
    decision: decision === "allow" || decision === "deny" ? decision : null,
    sessionId: row.session_id,
    toolInput: parseToolInput(row.tool_input),
    toolName: row.tool_name
  };
}
function rowToRich(row) {
  const responseKindRaw = typeof row.response_kind === "string" ? row.response_kind : "hook";
  const responseKind = responseKindRaw === "hook" || responseKindRaw === "pty" || responseKindRaw === "info" ? responseKindRaw : "hook";
  return {
    createdAt: row.created_at,
    decidedAt: row.decided_at ?? null,
    decision: row.decision ?? null,
    options: parseOptions(row.options),
    question: row.question ?? null,
    requestId: row.request_id,
    responseKind,
    sessionId: row.session_id,
    toolInput: parseToolInput(row.tool_input),
    toolName: row.tool_name
  };
}
const PR_GLOBAL_KEY = "__shooter_pending_requests_store";
const pendingRequestsStore = globalThis[PR_GLOBAL_KEY] || new PendingRequestsStore();
globalThis[PR_GLOBAL_KEY] = pendingRequestsStore;
function cleanup(maxAgeMs = MAX_AGE_MS) {
  pendingRequestsStore.cleanup(maxAgeMs);
}
function createPendingRequest(requestId, data) {
  cleanup();
  pendingRequestsStore.insert(requestId, data);
}
function getDecision(requestId) {
  const entry = pendingRequestsStore.getRich(requestId);
  if (!entry) {
    return { status: "not_found" };
  }
  if (entry.decision) {
    pendingRequestsStore.delete(requestId);
    return { decision: entry.decision, status: "decided" };
  }
  return { status: "pending" };
}
function getRichRequest(requestId) {
  return pendingRequestsStore.getRich(requestId);
}
function setDecision(requestId, decision) {
  return pendingRequestsStore.setDecision(requestId, decision);
}

export { cleanup as a, getDecision as b, createPendingRequest as c, getRichRequest as g, setDecision as s };
//# sourceMappingURL=pending-requests-8rWjrF6d.js.map
