/**
 * Abstract SQLite interface to decouple SessionStore from a specific SQLite
 * binding. Enables Bun standalone binary builds (bun:sqlite) while preserving
 * the existing better-sqlite3 path for Node.js.
 *
 * Two implementations:
 *   - NodeSqliteAdapter  — wraps better-sqlite3 (existing path, zero changes)
 *   - BunSqliteAdapter   — wraps bun:sqlite (Bun built-in, zero dependencies)
 *
 * The factory `createSqliteAdapter()` detects the runtime and returns the
 * correct adapter. Callers (SessionStore) only interact with the `SqliteAdapter`
 * interface — they never import better-sqlite3 or bun:sqlite directly.
 */
import { createRequire } from "node:module";
const _require = createRequire(import.meta.url);
// ---------------------------------------------------------------------------
// Node.js adapter (better-sqlite3)
// ---------------------------------------------------------------------------
class NodeStatement {
    stmt;
    constructor(stmt) {
        this.stmt = stmt;
    }
    all(...params) {
        return this.stmt.all(...params);
    }
    get(...params) {
        return this.stmt.get(...params);
    }
    run(...params) {
        return this.stmt.run(...params);
    }
}
class NodeSqliteAdapter {
    db;
    constructor(path) {
        const Db = _require("better-sqlite3");
        this.db = new Db(path);
    }
    prepare(sql) {
        return new NodeStatement(this.db.prepare(sql));
    }
    exec(sql) {
        this.db.exec(sql);
    }
    pragma(sql) {
        this.db.pragma(sql);
    }
    transaction(fn) {
        return this.db.transaction(fn);
    }
    close() {
        this.db.close();
    }
}
// ---------------------------------------------------------------------------
// Bun adapter (bun:sqlite)
// ---------------------------------------------------------------------------
/**
 * Statement wrapper for bun:sqlite. Bun's query() returns a Statement-like
 * object with identical method signatures (.all, .get, .run), so the wrapper
 * is a thin pass-through.
 */
class BunStatement {
    stmt;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    constructor(stmt) {
        this.stmt = stmt;
    }
    all(...params) {
        return this.stmt.all(...params);
    }
    get(...params) {
        return this.stmt.get(...params);
    }
    run(...params) {
        return this.stmt.run(...params);
    }
}
/**
 * SQLite adapter backed by bun:sqlite — Bun's built-in, zero-dependency
 * SQLite module. Used when `globalThis.Bun` is defined.
 *
 * PRAGMAs are executed via `exec("PRAGMA ...")` because bun:sqlite does not
 * expose a `.pragma()` convenience method.
 */
class BunSqliteAdapter {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    db;
    constructor(path) {
        const { Database } = _require("bun:sqlite");
        this.db = new Database(path, { create: true });
        this.db.exec("PRAGMA journal_mode = WAL");
        this.db.exec("PRAGMA foreign_keys = ON");
    }
    prepare(sql) {
        return new BunStatement(this.db.query(sql));
    }
    exec(sql) {
        this.db.exec(sql);
    }
    pragma(sql) {
        this.db.exec(`PRAGMA ${sql}`);
    }
    transaction(fn) {
        return this.db.transaction(fn);
    }
    close() {
        this.db.close();
    }
}
// ---------------------------------------------------------------------------
// Runtime detection + factory
// ---------------------------------------------------------------------------
function isBun() {
    return typeof globalThis.Bun !== "undefined";
}
/**
 * Create a SQLite adapter for the given filesystem path. Auto-detects the
 * runtime (Node.js → better-sqlite3, Bun → bun:sqlite) and returns the
 * matching implementation.
 */
export function createSqliteAdapter(path) {
    if (isBun()) {
        return new BunSqliteAdapter(path);
    }
    return new NodeSqliteAdapter(path);
}
