/**
 * @bytelyst/field-encrypt — Types
 *
 * Core type definitions for field-level encryption.
 */

/** Encrypted field stored in Cosmos DB or SQLite. */
export interface EncryptedField {
  /** Sentinel — always true for encrypted fields. */
  readonly __encrypted: true;
  /** Schema version for future algorithm changes. */
  readonly v: 1;
  /** Algorithm identifier. */
  readonly alg: 'aes-256-gcm';
  /** Ciphertext (hex-encoded). */
  readonly ct: string;
  /** Initialization vector (hex-encoded, 12 bytes / 24 hex chars). */
  readonly iv: string;
  /** GCM authentication tag (hex-encoded, 16 bytes / 32 hex chars). */
  readonly tag: string;
  /** DEK identifier — identifies which key to unwrap for decryption. */
  readonly dekId: string;
}

/** Wrapped DEK stored alongside data (e.g., in a `_encryption_keys` Cosmos container). */
export interface WrappedDek {
  /** Unique DEK identifier, e.g. `dek_user123_transcripts`. */
  readonly dekId: string;
  /** Wrapped (encrypted) DEK bytes (hex-encoded). */
  readonly wrappedKey: string;
  /** MEK name/version used to wrap this DEK. */
  readonly mekVersion: string;
  /** ISO 8601 creation timestamp. */
  readonly createdAt: string;
}

/** Options for encrypt/decrypt operations. */
export interface FieldEncryptContext {
  /** Scope for DEK isolation (typically userId). */
  readonly userId: string;
  /** Additional context for DEK naming and AAD (e.g., 'transcripts', 'notes'). */
  readonly context: string;
}

/** Key provider — abstraction over key storage backends. */
export interface KeyProvider {
  /** Wrap (encrypt) a DEK with the master key. Returns hex-encoded wrapped key + mek version string. */
  wrapKey(dek: Buffer): Promise<{ wrappedKey: string; mekVersion: string }>;
  /** Unwrap (decrypt) a wrapped DEK. Returns raw DEK buffer. */
  unwrapKey(wrappedKeyHex: string, mekVersion: string): Promise<Buffer>;
}

/** Supported key provider types. */
export type KeyProviderType = 'akv' | 'env' | 'memory';

/** DEK store — abstraction over DEK persistence. */
export interface DekStore {
  /** Get a wrapped DEK by its ID. Returns null if not found. */
  get(dekId: string): Promise<WrappedDek | null>;
  /** Store a wrapped DEK. */
  put(dek: WrappedDek): Promise<void>;
  /** List all DEK IDs (for rotation). */
  listIds(): Promise<string[]>;
  /** Delete a DEK. */
  delete(dekId: string): Promise<void>;
}

/** Configuration for createFieldEncryptor(). */
export interface FieldEncryptorConfig {
  /**
   * Master toggle — set to false to disable encryption entirely.
   * When disabled, encrypt() returns plaintext as-is and decrypt() passes through.
   * Default: true.
   */
  enabled?: boolean;
  /** Key provider type. */
  keyProvider: KeyProviderType;
  /** Azure Key Vault URL (required for 'akv' provider). */
  keyVaultUrl?: string;
  /** MEK name in AKV (required for 'akv' provider). */
  mekName?: string;
  /** Hex-encoded encryption key (required for 'env' provider). */
  encryptionKey?: string;
  /** DEK cache TTL in milliseconds (default: 15 minutes). */
  dekCacheTtlMs?: number;
  /** DEK cache max size (default: 1000). */
  dekCacheMaxSize?: number;
  /** DEK store implementation (default: in-memory). */
  dekStore?: DekStore;
}
