import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import Database from 'better-sqlite3';
import { mkdtempSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { runMigrations } from './migrate.js';

describe('migrate: notes tables', () => {
  let tmpRoot: string;
  let db: Database.Database;

  beforeEach(() => {
    tmpRoot = mkdtempSync(join(tmpdir(), 'migrate-notes-test-'));
    db = new Database(join(tmpRoot, 'test.db'));
  });

  afterEach(() => {
    db.close();
    rmSync(tmpRoot, { recursive: true, force: true });
  });

  it('creates note_index, note_subscriptions, pending_reindex, note_index_fts', () => {
    runMigrations(db);
    const tables = db
      // FTS5 virtual tables appear as type='table' in sqlite_master, not 'virtual'.
      .prepare("SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name")
      .all()
      .map((r: any) => r.name);
    expect(tables).toContain('note_index');
    expect(tables).toContain('note_subscriptions');
    expect(tables).toContain('pending_reindex');
    expect(tables).toContain('note_index_fts');
  });

  it('note_index_fts is kept in sync via triggers on note_index insert', () => {
    runMigrations(db);
    db.prepare(`INSERT INTO users (id, email) VALUES ('u1','u1@x.com')`).run();
    db.prepare(`
      INSERT INTO note_index (owner_id, folder, file_name, title, visibility, tags_json, content_size, content_hash, updated_at, body)
      VALUES ('u1','cve','foo.md','CVE foo','public','["cve"]',100,'h',1,'this is the body')
    `).run();
    const row: any = db.prepare(`SELECT title, tags, body FROM note_index_fts WHERE owner_id='u1'`).get();
    expect(row.title).toBe('CVE foo');
    expect(row.tags).toBe('["cve"]');
    expect(row.body).toBe('this is the body');
  });

  it('CASCADE deletes note_index rows when user is deleted', () => {
    runMigrations(db);
    db.prepare(`INSERT INTO users (id, email) VALUES ('u1','u1@x.com')`).run();
    db.prepare(`
      INSERT INTO note_index (owner_id, folder, file_name, visibility, updated_at, content_size, content_hash, body)
      VALUES ('u1','f','x.md','private',1,0,'h','')
    `).run();
    db.prepare(`DELETE FROM users WHERE id='u1'`).run();
    const count: any = db.prepare(`SELECT COUNT(*) c FROM note_index WHERE owner_id='u1'`).get();
    expect(count.c).toBe(0);
  });
});
