package infra

import (
	"database/sql"
	"os"
	"path/filepath"
	"testing"
)

func TestVaultIndexOpen_CreatesDB(t *testing.T) {
	t.Run("crea vault_index.db en tmpdir vacio", func(t *testing.T) {
		dir := t.TempDir()
		db, err := VaultIndexOpen(dir)
		if err != nil {
			t.Fatalf("VaultIndexOpen: %v", err)
		}
		defer db.Close()

		dbPath := filepath.Join(dir, "vault_index.db")
		if _, err := os.Stat(dbPath); os.IsNotExist(err) {
			t.Fatalf("vault_index.db no fue creado en %s", dir)
		}
	})
}

func TestVaultIndexOpen_Idempotent(t *testing.T) {
	t.Run("segunda apertura no falla (idempotente)", func(t *testing.T) {
		dir := t.TempDir()

		db1, err := VaultIndexOpen(dir)
		if err != nil {
			t.Fatalf("primera apertura: %v", err)
		}
		db1.Close()

		db2, err := VaultIndexOpen(dir)
		if err != nil {
			t.Fatalf("segunda apertura: %v", err)
		}
		db2.Close()
	})
}

func TestVaultIndexOpen_AppliesAllMigrations(t *testing.T) {
	t.Run("todas las tablas esperadas existen en sqlite_master", func(t *testing.T) {
		dir := t.TempDir()
		db, err := VaultIndexOpen(dir)
		if err != nil {
			t.Fatalf("VaultIndexOpen: %v", err)
		}
		defer db.Close()

		expectedTables := []string{
			"files",
			"csv_profiles",
			"pdf_extracts",
			"knowledge_docs",
		}
		for _, tbl := range expectedTables {
			assertTableExists(t, db, tbl)
		}
	})
}

func TestVaultIndexOpen_FTS5Works(t *testing.T) {
	t.Run("fts5 INSERT y MATCH funcionan", func(t *testing.T) {
		dir := t.TempDir()
		db, err := VaultIndexOpen(dir)
		if err != nil {
			t.Fatalf("VaultIndexOpen: %v", err)
		}
		defer db.Close()

		// Insert a row into files_fts (content='' table, manual INSERT required)
		_, err = db.Exec(`INSERT INTO files_fts(rel_path, content_text) VALUES (?, ?)`,
			"data/raw/informe_ventas.csv", "ventas trimestrales empresa")
		if err != nil {
			t.Fatalf("INSERT files_fts: %v", err)
		}

		var count int
		err = db.QueryRow(
			`SELECT count(*) FROM files_fts WHERE files_fts MATCH 'ventas'`,
		).Scan(&count)
		if err != nil {
			t.Fatalf("FTS MATCH query: %v", err)
		}
		if count != 1 {
			t.Errorf("FTS MATCH: got %d rows, want 1", count)
		}
	})
}

// assertTableExists verifies that a table (or virtual table) exists in sqlite_master.
func assertTableExists(t *testing.T, db *sql.DB, name string) {
	t.Helper()
	var exists int
	err := db.QueryRow(
		`SELECT count(*) FROM sqlite_master WHERE name = ?`, name,
	).Scan(&exists)
	if err != nil {
		t.Fatalf("sqlite_master query for %q: %v", name, err)
	}
	if exists == 0 {
		t.Errorf("table/vtable %q not found in sqlite_master", name)
	}
}
