import Database from 'better-sqlite3';
import { join, dirname } from 'path';
const SCHEMA = `
CREATE TABLE IF NOT EXISTS balance_cache (
  id INTEGER PRIMARY KEY CHECK (id = 1),
  balance_cents INTEGER NOT NULL DEFAULT 0,
  cost_per_file_cents INTEGER NOT NULL DEFAULT 3,
  fetched_at TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS pending_charges (
  id TEXT PRIMARY KEY,
  document_hash TEXT NOT NULL,
  amount_cents INTEGER NOT NULL DEFAULT 3,
  confirmed INTEGER NOT NULL DEFAULT 0,
  created_at TEXT NOT NULL
);
`;
export class LicenseCache {
    db;
    constructor(storagePath) {
        // Place _license.db alongside _registry.db in the parent directory,
        // NOT inside databases/ — prevents registry auto-discovery
        const parentDir = dirname(storagePath);
        // When storagePath is a root-level directory (e.g., /data in Docker),
        // dirname returns '/' which is unwritable. Use storagePath directly.
        const baseDir = (parentDir === '/' || parentDir === '.') ? storagePath : parentDir;
        const dbPath = join(baseDir, '_license.db');
        this.db = new Database(dbPath);
        this.db.pragma('journal_mode = WAL');
        this.db.exec(SCHEMA);
        // Idempotent migration: add cost_per_file_cents column if missing (existing databases)
        try {
            this.db.exec('ALTER TABLE balance_cache ADD COLUMN cost_per_file_cents INTEGER NOT NULL DEFAULT 3');
        }
        catch (_e) {
            // Column already exists — expected on non-first run
        }
        // Drop the free_tier table if it exists from a previous version
        this.db.exec('DROP TABLE IF EXISTS free_tier');
        // Migration: add balance_token column (server-signed by Cloudflare Worker)
        try {
            this.db.exec('ALTER TABLE balance_cache ADD COLUMN balance_token TEXT');
        }
        catch (_e) {
            // Column already exists
        }
    }
    getCachedBalance() {
        const row = this.db.prepare('SELECT balance_cents, cost_per_file_cents FROM balance_cache WHERE id = 1').get();
        return {
            balance_cents: row?.balance_cents ?? 0,
            cost_per_file_cents: row?.cost_per_file_cents ?? 3,
        };
    }
    setCachedBalance(cents, costPerFileCents) {
        this.db
            .prepare(`INSERT INTO balance_cache (id, balance_cents, cost_per_file_cents, fetched_at) VALUES (1, ?, ?, ?)
         ON CONFLICT(id) DO UPDATE SET balance_cents = excluded.balance_cents, cost_per_file_cents = excluded.cost_per_file_cents, fetched_at = excluded.fetched_at`)
            .run(cents, costPerFileCents, new Date().toISOString());
    }
    setBalanceToken(token) {
        this.db.prepare('UPDATE balance_cache SET balance_token = ? WHERE id = 1').run(token);
    }
    getBalanceToken() {
        const row = this.db.prepare('SELECT balance_token FROM balance_cache WHERE id = 1').get();
        return row?.balance_token ?? null;
    }
    getLastFetch() {
        const row = this.db.prepare('SELECT fetched_at FROM balance_cache WHERE id = 1').get();
        return row ? new Date(row.fetched_at) : null;
    }
    addPendingCharge(id, documentHash) {
        this.db
            .prepare('INSERT INTO pending_charges (id, document_hash, amount_cents, confirmed, created_at) VALUES (?, ?, 3, 0, ?)')
            .run(id, documentHash, new Date().toISOString());
    }
    confirmPendingCharge(id) {
        this.db.prepare('UPDATE pending_charges SET confirmed = 1 WHERE id = ?').run(id);
    }
    removePendingCharge(id) {
        this.db.prepare('DELETE FROM pending_charges WHERE id = ?').run(id);
    }
    getPendingCharges() {
        return this.db.prepare('SELECT * FROM pending_charges').all();
    }
    getPendingCount() {
        const row = this.db.prepare('SELECT COUNT(*) as count FROM pending_charges').get();
        return row.count;
    }
    close() {
        this.db.close();
    }
}
//# sourceMappingURL=cache.js.map