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 '../../db/migrate.js';
import { NotesRepository } from '../../notes/notes-repository.js';
import { NotesService } from '../../notes/notes-service.js';
import { executeNotesTools, TOOL_DEFS } from './notes.js';

describe('notes tools', () => {
  let tmpRoot: string;
  let db: Database.Database;
  let service: NotesService;
  let ctx: { notesService: NotesService; user: Express.User };

  beforeEach(() => {
    tmpRoot = mkdtempSync(join(tmpdir(), 'notes-tools-test-'));
    db = new Database(join(tmpRoot, 'test.db'));
    runMigrations(db);
    db.prepare(`INSERT INTO users (id, email, name) VALUES ('alice','a@x.com','Alice')`).run();
    const repo = new NotesRepository(db);
    service = new NotesService({ db, repo, userFolderRoot: tmpRoot, getUserOrgIds: () => [] });
    ctx = {
      notesService: service,
      user: {
        id: 'alice',
        role: 'user',
        orgIds: [],
        email: 'a@x.com',
        name: 'Alice',
        avatarUrl: null,
        status: 'active',
        defaultVisibility: 'private',
        defaultVisibilityOrgId: null,
      },
    };
  });

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

  it('exposes 3 TOOL_DEFS', () => {
    expect(Object.keys(TOOL_DEFS).sort()).toEqual(['ReadNote', 'SearchNotes', 'WriteNote']);
  });

  it('WriteNote writes a note and returns path', async () => {
    const result = await executeNotesTools('WriteNote', {
      folder: 'cve',
      file_name: 'foo.md',
      content: '---\nvisibility: public\n---\nbody',
    }, ctx);
    expect(result?.isError).toBeFalsy();
    expect(result?.output).toContain('cve/foo.md');
  });

  it('SearchNotes finds a written note via FTS', async () => {
    await executeNotesTools('WriteNote', {
      folder: 'cve',
      file_name: 'foo.md',
      content: '---\ntitle: kubernetes pod crash\nvisibility: public\n---\nbody',
    }, ctx);
    const result = await executeNotesTools('SearchNotes', { query: 'kubernetes' }, ctx);
    expect(result?.isError).toBeFalsy();
    expect(result?.output).toContain('foo.md');
  });

  it('ReadNote returns full body and FM', async () => {
    await executeNotesTools('WriteNote', {
      folder: 'cve',
      file_name: 'foo.md',
      content: '---\nvisibility: public\n---\nbody content',
    }, ctx);
    const result = await executeNotesTools('ReadNote', {
      owner_id: 'alice', folder: 'cve', file_name: 'foo.md',
    }, ctx);
    expect(result?.isError).toBeFalsy();
    expect(result?.output).toContain('body content');
  });
});
