/**
 * Synchronous read-through cache for the settings table.
 *
 * 27 call sites read settings synchronously — during startup, inside request
 * handlers, and from the guacd server bootstrap. On SQLite that works because
 * better-sqlite3 is synchronous; on Postgres or MySQL there is no synchronous
 * query at all, and making all 27 async would push `await` through code paths
 * that have no business being asynchronous.
 *
 * Settings are a handful of low-cardinality configuration rows that change
 * rarely and are read constantly, so they are cached in full. Writes go through
 * SettingsRepository, which updates the cache in the same call, and the cache is
 * primed once at startup.
 *
 * Known limitation with more than one instance: a write only updates the cache
 * of the process that made it. Other instances keep serving the old value until
 * their own refresh comes round (SETTINGS_CACHE_REFRESH_SECONDS, 30s default),
 * so a settings change takes up to that long to apply fleet-wide. Fixing it
 * properly needs cross-instance invalidation, which is not in place yet.
 */

let cache: Map<string, string> | null = null;

export function isSettingsCachePrimed(): boolean {
  return cache !== null;
}

/** Loads the full settings table. Called once during startup. */
export function primeSettingsCache(
  rows: { key: string; value: string }[],
): void {
  cache = new Map(rows.map((row) => [row.key, row.value]));
}

/**
 * Reads a cached setting.
 *
 * Returns null both for "not set" and "cache not primed yet" — every caller
 * already treats a missing setting as "use the default", and startup ordering
 * means a read before priming should behave the same way rather than throw.
 */
export function readCachedSetting(key: string): string | null {
  return cache?.get(key) ?? null;
}

/** Keeps the cache in step with a write. */
export function updateCachedSetting(key: string, value: string): void {
  cache?.set(key, value);
}

export function forgetCachedSetting(key: string): void {
  cache?.delete(key);
}

/** Test seam. */
export function resetSettingsCache(): void {
  cache = null;
}
