import { describe, expect, it } from 'vitest';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const currentDir = path.dirname(fileURLToPath(import.meta.url));
const migrationDir = path.resolve(currentDir, '../../src/infra/database/migrations');
const migrationFile = '050_create-memory-schema.sql';
const migrationPath = path.resolve(migrationDir, migrationFile);

function readMigration(): string {
  return fs.readFileSync(migrationPath, 'utf8');
}

describe('create memory schema migration', () => {
  it('exists and is ordered after the prior migration', () => {
    expect(fs.existsSync(migrationPath)).toBe(true);
    const migrations = fs
      .readdirSync(migrationDir)
      .filter((f) => f.endsWith('.sql'))
      .sort();
    const idx = migrations.indexOf(migrationFile);
    const prev = migrations.indexOf('049_add-multi-provider-payments-foundation.sql');
    expect(prev).not.toBe(-1);
    expect(idx).toBeGreaterThan(prev);
  });

  it('enables pgvector and creates the memory.memories table with a 1536-d vector', () => {
    const sql = readMigration();
    expect(sql).toMatch(/CREATE EXTENSION IF NOT EXISTS vector/i);
    expect(sql).toMatch(/CREATE SCHEMA IF NOT EXISTS memory/i);
    expect(sql).toMatch(/CREATE TABLE IF NOT EXISTS memory\.memories/i);
    expect(sql).toMatch(/embedding\s+VECTOR\(1536\)/i);
  });

  it('constrains kind to the four memory kinds', () => {
    const sql = readMigration();
    expect(sql).toMatch(
      /kind\s+TEXT\s+NOT NULL\s+CHECK\s*\(kind IN \('fact', 'decision', 'preference', 'reference'\)\)/i
    );
  });

  it('creates the HNSW vector index and the GIN full-text index for hybrid recall', () => {
    const sql = readMigration();
    expect(sql).toMatch(/USING hnsw \(embedding vector_cosine_ops\)/i);
    expect(sql).toMatch(/content_tsv\s+TSVECTOR GENERATED ALWAYS AS/i);
    expect(sql).toMatch(/USING gin \(content_tsv\)/i);
  });

  it('is idempotent on the trigger (DROP TRIGGER IF EXISTS before CREATE)', () => {
    const sql = readMigration();
    expect(sql).toMatch(/DROP TRIGGER IF EXISTS trg_memories_updated_at ON memory\.memories/i);
    const dropIdx = sql.indexOf('DROP TRIGGER IF EXISTS trg_memories_updated_at');
    const createIdx = sql.indexOf('CREATE TRIGGER trg_memories_updated_at');
    expect(dropIdx).toBeGreaterThan(-1);
    expect(createIdx).toBeGreaterThan(dropIdx);
  });
});
