import { Database } from 'bun:sqlite';
import { mkdirSync, existsSync } from 'node:fs';
import { homedir } from 'node:os';
import { join } from 'node:path';
let dbInstance = null;
export function getLocalDB() {
    if (dbInstance) {
        return dbInstance;
    }
    const configDir = join(homedir(), '.config', 'agentuity');
    if (!existsSync(configDir)) {
        mkdirSync(configDir, { recursive: true });
    }
    const dbPath = join(configDir, 'local.db');
    dbInstance = new Database(dbPath);
    initializeTables(dbInstance);
    cleanupOrphanedProjects(dbInstance);
    return dbInstance;
}
function initializeTables(db) {
    // KeyValue Storage table
    db.run(`
		CREATE TABLE IF NOT EXISTS kv_storage (
			project_path TEXT NOT NULL,
			name TEXT NOT NULL,
			key TEXT NOT NULL,
			value BLOB NOT NULL,
			content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
			expires_at INTEGER,
			created_at INTEGER NOT NULL,
			updated_at INTEGER NOT NULL,
			PRIMARY KEY (project_path, name, key)
		)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_kv_expires 
		ON kv_storage(expires_at) 
		WHERE expires_at IS NOT NULL
	`);
    // Stream Storage table
    db.run(`
		CREATE TABLE IF NOT EXISTS stream_storage (
			project_path TEXT NOT NULL,
			id TEXT PRIMARY KEY,
			name TEXT NOT NULL,
			metadata TEXT,
			content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
			data BLOB,
			size_bytes INTEGER NOT NULL DEFAULT 0,
			created_at INTEGER NOT NULL
		)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_stream_name 
		ON stream_storage(project_path, name)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_stream_metadata 
		ON stream_storage(metadata)
	`);
    // Vector Storage table
    db.run(`
		CREATE TABLE IF NOT EXISTS vector_storage (
			project_path TEXT NOT NULL,
			name TEXT NOT NULL,
			id TEXT PRIMARY KEY,
			key TEXT NOT NULL,
			embedding TEXT NOT NULL,
			document TEXT,
			metadata TEXT,
			created_at INTEGER NOT NULL,
			updated_at INTEGER NOT NULL,
			UNIQUE (project_path, name, key)
		)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_vector_lookup 
		ON vector_storage(project_path, name, key)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_vector_name 
		ON vector_storage(project_path, name)
	`);
    // Task Storage table
    db.run(`
		CREATE TABLE IF NOT EXISTS task_storage (
			project_path TEXT NOT NULL,
			id TEXT NOT NULL,
			title TEXT NOT NULL,
			description TEXT,
			metadata TEXT,
			priority TEXT NOT NULL DEFAULT 'none',
			parent_id TEXT,
			type TEXT NOT NULL,
			status TEXT NOT NULL DEFAULT 'open',
			open_date TEXT,
			in_progress_date TEXT,
			closed_date TEXT,
			created_id TEXT NOT NULL,
			assigned_id TEXT,
			closed_id TEXT,
			deleted INTEGER NOT NULL DEFAULT 0,
			created_at INTEGER NOT NULL,
			updated_at INTEGER NOT NULL,
			PRIMARY KEY (project_path, id)
		)
	`);
    // Migration: add deleted column for existing databases
    try {
        db.run('ALTER TABLE task_storage ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0');
    }
    catch {
        // Column already exists
    }
    // Task Changelog table
    db.run(`
		CREATE TABLE IF NOT EXISTS task_changelog_storage (
			project_path TEXT NOT NULL,
			id TEXT NOT NULL,
			task_id TEXT NOT NULL,
			field TEXT NOT NULL,
			old_value TEXT,
			new_value TEXT,
			created_at INTEGER NOT NULL,
			PRIMARY KEY (project_path, id)
		)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_task_changelog_lookup
		ON task_changelog_storage(project_path, task_id)
	`);
    // Task Comment table
    db.run(`
		CREATE TABLE IF NOT EXISTS task_comment_storage (
			project_path TEXT NOT NULL,
			id TEXT NOT NULL,
			task_id TEXT NOT NULL,
			user_id TEXT NOT NULL,
			body TEXT NOT NULL,
			created_at INTEGER NOT NULL,
			updated_at INTEGER NOT NULL,
			PRIMARY KEY (project_path, id)
		)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_task_comment_lookup
		ON task_comment_storage(project_path, task_id)
	`);
    // Task Tag table
    db.run(`
		CREATE TABLE IF NOT EXISTS task_tag_storage (
			project_path TEXT NOT NULL,
			id TEXT NOT NULL,
			name TEXT NOT NULL,
			color TEXT,
			created_at INTEGER NOT NULL,
			PRIMARY KEY (project_path, id)
		)
	`);
    // Task-Tag association table
    db.run(`
		CREATE TABLE IF NOT EXISTS task_tag_association_storage (
			project_path TEXT NOT NULL,
			task_id TEXT NOT NULL,
			tag_id TEXT NOT NULL,
			PRIMARY KEY (project_path, task_id, tag_id)
		)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_task_tag_assoc_task
		ON task_tag_association_storage(project_path, task_id)
	`);
    db.run(`
		CREATE INDEX IF NOT EXISTS idx_task_tag_assoc_tag
		ON task_tag_association_storage(project_path, tag_id)
	`);
    // Task User table
    db.run(`
		CREATE TABLE IF NOT EXISTS task_user_storage (
			project_path TEXT NOT NULL,
			id TEXT NOT NULL,
			name TEXT NOT NULL,
			type TEXT NOT NULL DEFAULT 'human',
			created_at INTEGER NOT NULL,
			PRIMARY KEY (project_path, id)
		)
	`);
    // Task Project table
    db.run(`
		CREATE TABLE IF NOT EXISTS task_project_storage (
			project_path TEXT NOT NULL,
			id TEXT NOT NULL,
			name TEXT NOT NULL,
			created_at INTEGER NOT NULL,
			PRIMARY KEY (project_path, id)
		)
	`);
}
function cleanupOrphanedProjects(db) {
    // Get the current project path to exclude from cleanup
    const currentProjectPath = process.cwd();
    // Query all tables for unique project paths
    const kvPaths = db.query('SELECT DISTINCT project_path FROM kv_storage').all();
    const streamPaths = db.query('SELECT DISTINCT project_path FROM stream_storage').all();
    const vectorPaths = db.query('SELECT DISTINCT project_path FROM vector_storage').all();
    const taskPaths = db.query('SELECT DISTINCT project_path FROM task_storage').all();
    const taskChangelogPaths = db
        .query('SELECT DISTINCT project_path FROM task_changelog_storage')
        .all();
    const taskCommentPaths = db
        .query('SELECT DISTINCT project_path FROM task_comment_storage')
        .all();
    const taskTagPaths = db
        .query('SELECT DISTINCT project_path FROM task_tag_storage')
        .all();
    const taskTagAssocPaths = db
        .query('SELECT DISTINCT project_path FROM task_tag_association_storage')
        .all();
    const taskUserPaths = db
        .query('SELECT DISTINCT project_path FROM task_user_storage')
        .all();
    const taskProjectPaths = db
        .query('SELECT DISTINCT project_path FROM task_project_storage')
        .all();
    // Combine and deduplicate all project paths
    const allPaths = new Set();
    [
        ...kvPaths,
        ...streamPaths,
        ...vectorPaths,
        ...taskPaths,
        ...taskChangelogPaths,
        ...taskCommentPaths,
        ...taskTagPaths,
        ...taskTagAssocPaths,
        ...taskUserPaths,
        ...taskProjectPaths,
    ].forEach((row) => {
        allPaths.add(row.project_path);
    });
    // Check which paths no longer exist and are not the current project
    const pathsToDelete = [];
    for (const path of allPaths) {
        if (path !== currentProjectPath && !existsSync(path)) {
            pathsToDelete.push(path);
        }
    }
    // Delete data for removed projects
    if (pathsToDelete.length > 0) {
        const placeholders = pathsToDelete.map(() => '?').join(', ');
        // Delete from all tables
        const deleteKv = db.prepare(`DELETE FROM kv_storage WHERE project_path IN (${placeholders})`);
        const deleteStream = db.prepare(`DELETE FROM stream_storage WHERE project_path IN (${placeholders})`);
        const deleteVector = db.prepare(`DELETE FROM vector_storage WHERE project_path IN (${placeholders})`);
        const deleteTasks = db.prepare(`DELETE FROM task_storage WHERE project_path IN (${placeholders})`);
        const deleteTaskChangelog = db.prepare(`DELETE FROM task_changelog_storage WHERE project_path IN (${placeholders})`);
        const deleteTaskComments = db.prepare(`DELETE FROM task_comment_storage WHERE project_path IN (${placeholders})`);
        const deleteTaskTags = db.prepare(`DELETE FROM task_tag_storage WHERE project_path IN (${placeholders})`);
        const deleteTaskTagAssoc = db.prepare(`DELETE FROM task_tag_association_storage WHERE project_path IN (${placeholders})`);
        const deleteTaskUsers = db.prepare(`DELETE FROM task_user_storage WHERE project_path IN (${placeholders})`);
        const deleteTaskProjects = db.prepare(`DELETE FROM task_project_storage WHERE project_path IN (${placeholders})`);
        deleteKv.run(...pathsToDelete);
        deleteStream.run(...pathsToDelete);
        deleteVector.run(...pathsToDelete);
        deleteTasks.run(...pathsToDelete);
        deleteTaskChangelog.run(...pathsToDelete);
        deleteTaskComments.run(...pathsToDelete);
        deleteTaskTags.run(...pathsToDelete);
        deleteTaskTagAssoc.run(...pathsToDelete);
        deleteTaskUsers.run(...pathsToDelete);
        deleteTaskProjects.run(...pathsToDelete);
        console.log(`[LocalDB] Cleaned up data for ${pathsToDelete.length} orphaned project(s)`);
    }
}
export function closeLocalDB() {
    if (dbInstance) {
        dbInstance.close();
        dbInstance = null;
    }
}
//# sourceMappingURL=_db.js.map