/**
 * Machine-level Agent Registry
 *
 * Tracks all agents across all projects in a single SQLite database
 * at ~/.prlt/agents.db. This provides a global view of agent activity
 * regardless of which workspace they belong to.
 */
import Database from 'better-sqlite3';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as os from 'node:os';
import { throwIfNativeBindingError } from '../database/native-validation.js';
// =============================================================================
// Schema
// =============================================================================
const REGISTRY_SCHEMA = `
CREATE TABLE IF NOT EXISTS agents (
  agent_name TEXT NOT NULL,
  project_path TEXT NOT NULL,
  session_id TEXT,
  ticket_id TEXT,
  status TEXT NOT NULL DEFAULT 'running' CHECK (status IN ('running', 'idle', 'completed')),
  spawned_at TEXT NOT NULL,
  last_seen_at TEXT NOT NULL,
  PRIMARY KEY (agent_name, project_path)
);

CREATE INDEX IF NOT EXISTS idx_registry_status ON agents(status);
CREATE INDEX IF NOT EXISTS idx_registry_project ON agents(project_path);
`;
// =============================================================================
// Helpers
// =============================================================================
function rowToMachineAgent(row) {
    return {
        agentName: row.agent_name,
        projectPath: row.project_path,
        sessionId: row.session_id,
        ticketId: row.ticket_id,
        status: row.status,
        spawnedAt: row.spawned_at,
        lastSeenAt: row.last_seen_at,
    };
}
function getMachineRegistryPath() {
    return path.join(os.homedir(), '.prlt', 'agents.db');
}
// =============================================================================
// Database Access
// =============================================================================
/**
 * Open (or create) the machine-level agent registry at ~/.prlt/agents.db.
 * Ensures the ~/.prlt directory and schema exist.
 */
export function openMachineRegistry() {
    const dbPath = getMachineRegistryPath();
    const dir = path.dirname(dbPath);
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
    }
    try {
        const db = new Database(dbPath);
        db.pragma('journal_mode = WAL');
        db.pragma('busy_timeout = 3000');
        db.exec(REGISTRY_SCHEMA);
        return db;
    }
    catch (error) {
        throwIfNativeBindingError(error, 'machine agent registry');
        throw error;
    }
}
// =============================================================================
// Write Operations
// =============================================================================
/**
 * Register an agent spawn in the machine registry.
 * Uses INSERT OR REPLACE so re-spawning the same agent updates the record.
 */
export function registerAgent(params) {
    const db = openMachineRegistry();
    try {
        const now = new Date().toISOString();
        db.prepare(`
      INSERT OR REPLACE INTO agents (agent_name, project_path, session_id, ticket_id, status, spawned_at, last_seen_at)
      VALUES (?, ?, ?, ?, 'running', ?, ?)
    `).run(params.agentName, params.projectPath, params.sessionId ?? null, params.ticketId ?? null, now, now);
    }
    finally {
        db.close();
    }
}
/**
 * Update the status of an agent in the machine registry.
 */
export function updateAgentStatus(agentName, projectPath, status) {
    const db = openMachineRegistry();
    try {
        const now = new Date().toISOString();
        db.prepare(`
      UPDATE agents SET status = ?, last_seen_at = ?
      WHERE agent_name = ? AND project_path = ?
    `).run(status, now, agentName, projectPath);
    }
    finally {
        db.close();
    }
}
/**
 * Touch the last_seen_at timestamp for a running agent.
 */
export function touchAgentLastSeen(agentName, projectPath) {
    const db = openMachineRegistry();
    try {
        const now = new Date().toISOString();
        db.prepare(`
      UPDATE agents SET last_seen_at = ?
      WHERE agent_name = ? AND project_path = ?
    `).run(now, agentName, projectPath);
    }
    finally {
        db.close();
    }
}
// =============================================================================
// Read Operations
// =============================================================================
/**
 * Get all agents in the machine registry, optionally filtered.
 */
export function getMachineAgents(filters) {
    const db = openMachineRegistry();
    try {
        let sql = 'SELECT * FROM agents';
        const conditions = [];
        const params = [];
        if (filters?.status) {
            conditions.push('status = ?');
            params.push(filters.status);
        }
        if (filters?.projectPath) {
            conditions.push('project_path = ?');
            params.push(filters.projectPath);
        }
        if (conditions.length > 0) {
            sql += ' WHERE ' + conditions.join(' AND ');
        }
        sql += ' ORDER BY last_seen_at DESC';
        const rows = db.prepare(sql).all(...params);
        return rows.map(rowToMachineAgent);
    }
    finally {
        db.close();
    }
}
/**
 * Get a single agent by name and project path.
 */
export function getMachineAgent(agentName, projectPath) {
    const db = openMachineRegistry();
    try {
        const row = db.prepare('SELECT * FROM agents WHERE agent_name = ? AND project_path = ?').get(agentName, projectPath);
        return row ? rowToMachineAgent(row) : undefined;
    }
    finally {
        db.close();
    }
}
//# sourceMappingURL=index.js.map