import { sql } from 'drizzle-orm'
import type { Querier, Dialect } from './index.js'

/**
 * Execute fn under an advisory lock.
 * - Postgres: acquires pg_advisory_xact_lock(key) within the transaction
 * - SQLite: passthrough (single-writer serializes at write-lock grain)
 *
 * BEHAVIORAL NOTE: PG blocks concurrent callers per-key; SQLite serializes
 * at coarser grain (the write lock). Callers needing fine-grained fairness
 * must know SQLite has different timing characteristics.
 */
export async function withAdvisoryLock<T>(
  db: Querier<any>,
  key: bigint,
  fn: () => Promise<T>,
  dialect: Dialect
): Promise<T> {
  if (dialect === 'sqlite') {
    // SQLite: single-writer, no per-key locking needed
    return fn()
  }

  // Postgres: acquire advisory lock (released at tx end)
  await (db as any).execute(sql`SELECT pg_advisory_xact_lock(${key})`)
  return fn()
}