// src/lib/db-worker.ts
import { parentPort, workerData } from "worker_threads";
if (!parentPort) {
  throw new Error("DB worker requires parentPort");
}
var port = parentPort;
function serializeError(error) {
  if (error instanceof Error) {
    return {
      name: error.name,
      message: error.message,
      stack: error.stack,
      code: typeof error.code === "string" ? error.code : void 0
    };
  }
  return {
    name: "Error",
    message: String(error)
  };
}
async function loadSqliteModule() {
  const originalEmitWarning = process.emitWarning;
  const importDynamic = new Function("specifier", "return import(specifier);");
  process.emitWarning = ((warning, options, ...args) => {
    const type = typeof options === "string" ? options : void 0;
    const message = warning instanceof Error ? warning.message : String(warning);
    if (type === "ExperimentalWarning" && message.includes("SQLite")) {
      return;
    }
    Reflect.apply(originalEmitWarning, process, [warning, options, ...args]);
  });
  try {
    return await importDynamic("node:sqlite");
  } finally {
    process.emitWarning = originalEmitWarning;
  }
}
async function loadMigrationModule() {
  const currentUrl = new URL(import.meta.url);
  const specifier = currentUrl.pathname.endsWith("/src/lib/db-worker.ts") ? new URL("./db-migrations.ts", currentUrl).href : new URL("./db-migrations.js", currentUrl).href;
  const importDynamic = new Function("specifier", "return import(specifier);");
  return await importDynamic(specifier);
}
function setDefensiveMode(db) {
  const maybeDb = db;
  if (typeof maybeDb.enableDefensive === "function") {
    maybeDb.enableDefensive(true);
  }
}
function runStatement(db, statement) {
  return db.prepare(statement.sql).run(...statement.params ?? []);
}
function getStatement(db, statement) {
  return db.prepare(statement.sql).get(...statement.params ?? []);
}
function allStatement(db, statement) {
  return db.prepare(statement.sql).all(...statement.params ?? []);
}
async function main() {
  const { DatabaseSync } = await loadSqliteModule();
  const { runMigrations } = await loadMigrationModule();
  const { filename } = workerData;
  const db = new DatabaseSync(filename);
  db.exec(`
    PRAGMA journal_mode = WAL;
    PRAGMA synchronous = FULL;
    PRAGMA busy_timeout = 5000;
    PRAGMA foreign_keys = ON;
  `);
  await runMigrations(db);
  setDefensiveMode(db);
  port.postMessage({ type: "ready" });
  port.on("message", (message) => {
    try {
      switch (message.type) {
        case "exec":
          db.exec(message.payload.sql);
          port.postMessage({
            type: "result",
            id: message.id,
            result: null
          });
          return;
        case "run":
          port.postMessage({
            type: "result",
            id: message.id,
            result: runStatement(db, message.payload)
          });
          return;
        case "get":
          port.postMessage({
            type: "result",
            id: message.id,
            result: getStatement(db, message.payload) ?? null
          });
          return;
        case "all":
          port.postMessage({
            type: "result",
            id: message.id,
            result: allStatement(db, message.payload)
          });
          return;
        case "batch":
          if (message.payload.transactional) {
            db.exec("BEGIN");
          }
          try {
            for (const command of message.payload.commands) {
              if ((command.params ?? []).length === 0) {
                db.exec(command.sql);
              } else {
                runStatement(db, command);
              }
            }
            if (message.payload.transactional) {
              db.exec("COMMIT");
            }
          } catch (error) {
            if (message.payload.transactional) {
              try {
                db.exec("ROLLBACK");
              } catch {
              }
            }
            throw error;
          }
          port.postMessage({
            type: "result",
            id: message.id,
            result: null
          });
          return;
        case "close":
          db.close();
          port.postMessage({
            type: "result",
            id: message.id,
            result: null
          });
          setImmediate(() => process.exit(0));
          return;
      }
    } catch (error) {
      port.postMessage({
        type: "error",
        id: message.id,
        error: serializeError(error)
      });
    }
  });
}
void main().catch((error) => {
  port.postMessage({
    type: "fatal",
    error: serializeError(error)
  });
  process.exit(1);
});
