import {
  describe,
  expect,
  it,
  vi
} from 'vitest';

import { executeMobileSqliteStatements } from './mobile-sqlite-execute.rules';
import {
  MOBILE_SQLITE_SCHEMA_VERSION,
  buildMobileSqliteSchemaStatements,
  resolveMobileSqliteMigrationStatements
} from './mobile-sqlite-schema.rules';

describe('mobile-sqlite-schema.rules', () => {
  it('returns one statement per DDL operation for a fresh database', () => {
    const statements = resolveMobileSqliteMigrationStatements(0);

    expect(statements.length).toBe(buildMobileSqliteSchemaStatements().length);
    expect(statements.length).toBeGreaterThan(1);

    for (const statement of statements) {
      expect(statement.trim().length).toBeGreaterThan(0);
      expect(statement).not.toMatch(/;\s*CREATE/i);
    }
  });

  it('returns no statements when the stored schema version is current', () => {
    expect(resolveMobileSqliteMigrationStatements(MOBILE_SQLITE_SCHEMA_VERSION)).toEqual([]);
  });

  it('executes each migration statement separately', async () => {
    const execute = vi.fn(() => Promise.resolve());
    const statements = resolveMobileSqliteMigrationStatements(0).slice(0, 3);

    await executeMobileSqliteStatements(execute, statements);

    expect(execute).toHaveBeenCalledTimes(3);
    expect(execute.mock.calls.map(([statement]) => statement)).toEqual(statements);
    expect(execute.mock.calls[0]?.[0]).toMatch(/^CREATE TABLE IF NOT EXISTS messages/);
    expect(execute.mock.calls[1]?.[0]).toMatch(/^CREATE INDEX IF NOT EXISTS idx_messages_room_id/);
  });
});
