/**
 * Process-wide store registry, configured once at server startup from the
 * `storage` block in `wrnexus.config.ts` (mirrors `@wrnexus/db`'s registry).
 * Handlers then call `getStore("<name>")` — or omit the name for the default.
 */

import type { StorageConfig, StorageDriver, StoreAccess, StoreConfig } from "./driver.ts";
import { localDriver } from "./adapters/local.ts";
import { s3Driver } from "./adapters/s3.ts";

export interface Store {
  name: string;
  access: StoreAccess;
  driver: StorageDriver;
  config: StoreConfig;
}

const stores = new Map<string, Store>();
let defaultName: string | undefined;

/** Build a driver per configured store. Safe to call again (fully replaces). */
export function configureStorage(config: StorageConfig | undefined, appRoot: string): void {
  stores.clear();
  defaultName = undefined;
  if (!config?.stores) return;
  for (const [name, cfg] of Object.entries(config.stores)) {
    const driver = cfg.driver === "s3" ? s3Driver(cfg) : localDriver(cfg, appRoot);
    stores.set(name, { name, access: cfg.access, driver, config: cfg });
  }
  defaultName = config.default ?? Object.keys(config.stores)[0];
}

/** Whether the default (or a named) store is configured. */
export function hasStorage(name?: string): boolean {
  const n = name ?? defaultName;
  return !!n && stores.has(n);
}

/** The default store, or a named one. Throws if it isn't configured. */
export function getStore(name?: string): Store {
  const n = name ?? defaultName;
  const store = n ? stores.get(n) : undefined;
  if (!store) {
    throw new Error(
      n
        ? `No storage store '${n}'. Add it under storage.stores in wrnexus.config.ts.`
        : "No storage configured. Add a `storage` block to wrnexus.config.ts.",
    );
  }
  return store;
}

/** Names of all configured stores. */
export function storeNames(): string[] {
  return [...stores.keys()];
}
