import type BetterSqlite3 from "better-sqlite3";

const auditRefPattern = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,159}$/;
const safeStringPattern = /^[A-Za-z0-9_.:@-]{1,160}$/;
const forbiddenKeys = new Set([
  "absolute_path", "api_key", "body", "code_hmac", "content", "credential", "email", "image",
  "image_content", "password", "path", "prompt", "secret", "session_token", "verification_code", "whitelist",
]);
const forbiddenKeyFragments = ["content", "credential", "email", "image", "password", "path", "prompt", "secret", "token"];

function safeSummaryValue(value: unknown, depth: number): boolean {
  if (depth > 3) return false;
  if (value === null || typeof value === "boolean") return true;
  if (typeof value === "number") return Number.isSafeInteger(value);
  if (typeof value === "string") return safeStringPattern.test(value) && !value.includes("@");
  if (Array.isArray(value)) return value.length <= 20 && value.every((entry) => safeSummaryValue(entry, depth + 1));
  if (!value || typeof value !== "object") return false;
  const entries = Object.entries(value);
  return entries.length <= 32 && entries.every(([key, entry]) => (
    auditRefPattern.test(key)
    && !forbiddenKeys.has(key.toLowerCase())
    && !forbiddenKeyFragments.some((fragment) => key.toLowerCase().includes(fragment))
    && safeSummaryValue(entry, depth + 1)
  ));
}

export function configureWorkerDatabase(database: BetterSqlite3.Database) {
  database.pragma("journal_mode = WAL");
  database.pragma("foreign_keys = ON");
  database.pragma("synchronous = FULL");
  database.pragma("busy_timeout = 5000");
  database.function("dada_audit_ref_is_safe", { deterministic: true }, (value: unknown) => (
    typeof value === "string" && auditRefPattern.test(value) ? 1 : 0
  ));
  database.function("dada_audit_summary_is_safe", { deterministic: true }, (value: unknown) => {
    if (typeof value !== "string" || Buffer.byteLength(value, "utf8") > 2_048) return 0;
    try {
      return safeSummaryValue(JSON.parse(value), 0) ? 1 : 0;
    } catch {
      return 0;
    }
  });
  database.function("dada_allow_retention_purge", { deterministic: false }, () => 0);
  database.function("dada_retention_purge_now", { deterministic: false }, () => 0);
  database.function("dada_allow_privacy_purge", { deterministic: false }, () => 0);
  database.function("dada_privacy_purge_subject", { deterministic: false }, () => "");
}
