/**
 * Storage driver contract + config types.
 *
 * A `StorageDriver` is the low-level object store (local disk, S3, …). It knows
 * how to put/get/delete raw bytes under a key — nothing about HTTP, multipart
 * parsing, validation, or URLs. The registry (`client.ts`) builds one driver per
 * configured store and the upload layer (`upload.ts`) drives them. This mirrors
 * `@wrnexus/db`'s driver/adapter split.
 */

/** Whether a store's objects are world-readable or served behind app auth. */
export type StoreAccess = "public" | "private";

/** An object read back from a store. */
export interface StoredObject {
  /** Object bytes as a web stream (preferred) or a buffer. */
  body: ReadableStream<Uint8Array> | Uint8Array;
  /** MIME type to serve with. */
  contentType: string;
  /** Size in bytes, when known. */
  size?: number;
}

/** Metadata passed alongside the bytes on `put`. */
export interface PutMeta {
  contentType: string;
  /** Original client filename (informational only — NEVER used as a path). */
  filename?: string;
}

/** The low-level object store. Implementations: `adapters/local.ts`, `adapters/s3.ts`. */
export interface StorageDriver {
  /** Persist `data` under `key` (overwrites). */
  put(key: string, data: Uint8Array, meta: PutMeta): Promise<void>;
  /** Fetch an object, or `null` if it doesn't exist. */
  get(key: string): Promise<StoredObject | null>;
  /** Remove an object. No error if it's already gone. */
  delete(key: string): Promise<void>;
  /**
   * A directly-servable absolute URL for a PUBLIC object (e.g. an S3/CDN URL), or
   * `null` when the framework should serve it (local public stores). Private
   * stores always return `null`.
   */
  publicUrl(key: string): string | null;
}

/** Local-disk store. `dir` is resolved against the app root when relative. */
export interface LocalStoreConfig {
  driver: "local";
  access: StoreAccess;
  /** Directory the files live under (e.g. "uploads/public"). */
  dir: string;
  /** Reject files larger than this many bytes (per file). */
  maxBytes?: number;
  /** Allowed types: MIME (`"image/*"`, `"application/pdf"`) and/or extensions (`".pdf"`). */
  accept?: string[];
}

/** S3 / S3-compatible store (AWS, Cloudflare R2, Backblaze B2, MinIO, DO Spaces). */
export interface S3StoreConfig {
  driver: "s3";
  access: StoreAccess;
  bucket: string;
  region: string;
  accessKeyId: string;
  secretAccessKey: string;
  /**
   * Custom endpoint for non-AWS services, e.g.
   * `https://<acct>.r2.cloudflarestorage.com`. Omit for AWS S3.
   */
  endpoint?: string;
  /** Force path-style URLs (`/bucket/key`). Defaults on for custom endpoints. */
  forcePathStyle?: boolean;
  /** Public base URL for `publicUrl()` (a CDN or public bucket domain). */
  publicBaseUrl?: string;
  maxBytes?: number;
  accept?: string[];
}

export type StoreConfig = LocalStoreConfig | S3StoreConfig;

/** The `storage` block in `wrnexus.config.ts`. */
export interface StorageConfig {
  /** Name of the store used when a call omits one. Defaults to the first store. */
  default?: string;
  /** Named stores, reached with `getStore("<name>")` / `upload("<name>", …)`. */
  stores: Record<string, StoreConfig>;
}
