/**
 * TestWrappingAdapter: Real blob store adapter for testing
 *
 * This adapter ACTUALLY wraps binary data in JSON (like production storage)
 * to properly test the unwrap logic in BlobStorage.
 *
 * Unlike InMemoryBlobAdapter which stores Buffers directly,
 * this adapter simulates real storage behavior:
 * 1. Compresses with gzip
 * 2. Wraps binary as {_binary: true, data: "base64..."}
 * 3. Parses JSON on read (returns JS object, not Buffer)
 *
 * This ensures tests exercise the ACTUAL code path that caused v5.10.0 regression.
 */

import { BlobStoreAdapter } from '../../src/storage/blobStorage.js'
import { gzip, gunzip } from 'zlib'
import { promisify } from 'util'

const gzipAsync = promisify(gzip)
const gunzipAsync = promisify(gunzip)

export class TestWrappingAdapter implements BlobStoreAdapter {
  private storage = new Map<string, Buffer>()

  async get(key: string): Promise<any | undefined> {
    const compressed = this.storage.get(key)
    if (!compressed) {
      return undefined
    }

    // Decompress (like real storage)
    const decompressed = await gunzipAsync(compressed)

    // Parse JSON (like real storage)
    // This returns a JS object: {_binary: true, data: "base64..."}
    // NOT a Buffer!
    return JSON.parse(decompressed.toString())
  }

  async put(key: string, data: Buffer): Promise<void> {
    // Use key-based dispatch (matches the baseStorage blob adapter)
    // NO GUESSING - key format explicitly declares data type
    const obj = key.includes('-meta:') || key.startsWith('ref:')
      ? JSON.parse(data.toString())  // Metadata/refs: ALWAYS JSON
      : { _binary: true, data: data.toString('base64') }  // Blobs: ALWAYS binary

    // Stringify to JSON
    const jsonStr = JSON.stringify(obj)

    // Compress (like real storage)
    const compressed = await gzipAsync(Buffer.from(jsonStr))

    // Store compressed data
    this.storage.set(key, compressed)
  }

  async delete(key: string): Promise<void> {
    this.storage.delete(key)
  }

  async list(prefix: string): Promise<string[]> {
    const keys: string[] = []
    for (const key of this.storage.keys()) {
      if (key.startsWith(prefix)) {
        keys.push(key)
      }
    }
    return keys
  }

  /**
   * Clear all storage (for test cleanup)
   */
  clear(): void {
    this.storage.clear()
  }

  /**
   * Get storage size (for testing)
   */
  size(): number {
    return this.storage.size
  }
}
