#!/usr/bin/env bun
/**
 * validate-schema.ts — Apply canonical.sql to an in-memory SQLite database
 * and extract structural metadata for CI comparison.
 *
 * Usage: bun tools/validate-schema.ts
 * Output: JSON to stdout with tables, columns, indexes, and schema version.
 */

import { Database } from "bun:sqlite";
import { readFileSync } from "fs";
import { join } from "path";

// ── Load canonical DDL ────────────────────────────────────────────────────────

const schemaPath = join(import.meta.dir, "..", "schema", "canonical.sql");
let ddl: string;
try {
  ddl = readFileSync(schemaPath, "utf-8");
} catch (err) {
  console.error(`Failed to read ${schemaPath}: ${err}`);
  process.exit(1);
}

// ── Apply to in-memory DB ─────────────────────────────────────────────────────

const db = new Database(":memory:");

try {
  db.exec(ddl);
} catch (err) {
  console.error(`Schema application failed: ${err}`);
  process.exit(1);
}

// ── Extract metadata ──────────────────────────────────────────────────────────

interface ColumnInfo {
  cid: number;
  name: string;
  type: string;
  notnull: number;
  dflt_value: string | null;
  pk: number;
}

interface TableMeta {
  name: string;
  type: string; // 'table' | 'virtual'
  columns: ColumnInfo[];
  indexes: string[];
}

// Get all tables and virtual tables from sqlite_master
const masterRows = db
  .prepare(
    `SELECT name, type FROM sqlite_master
     WHERE type IN ('table', 'virtual table')
       AND name NOT LIKE 'sqlite_%'
       AND name NOT LIKE '%_content'
       AND name NOT LIKE '%_data'
       AND name NOT LIKE '%_idx'
       AND name NOT LIKE '%_config'
       AND name NOT LIKE '%_docsize'
     ORDER BY name`,
  )
  .all() as Array<{ name: string; type: string }>;

const tables: TableMeta[] = [];

for (const { name, type } of masterRows) {
  // Get column info (not available for FTS5 virtual tables)
  let columns: ColumnInfo[] = [];
  try {
    columns = db
      .prepare(`PRAGMA table_info('${name}')`)
      .all() as ColumnInfo[];
  } catch {
    // FTS5 tables don't support table_info
  }

  // Get indexes for this table
  const indexRows = db
    .prepare(
      `SELECT name FROM sqlite_master
       WHERE type = 'index' AND tbl_name = ?
       ORDER BY name`,
    )
    .all(name) as Array<{ name: string }>;

  tables.push({
    name,
    type: type === "table" ? "table" : "virtual",
    columns,
    indexes: indexRows.map((r) => r.name),
  });
}

// ── Output ────────────────────────────────────────────────────────────────────

const output = {
  schemaFile: "schema/canonical.sql",
  version: 1,
  tableCount: tables.length,
  tables,
};

console.log(JSON.stringify(output, null, 2));
db.close();
