import { sha256 } from '@noble/hashes/sha2.js';

/**
 * Streaming SHA-256 wrapper.
 *
 * SubtleCrypto exposes only one-shot `digest`. Streams need incremental
 * hashing so the receiver doesn't materialize the full plaintext before
 * verifying integrity (NF2: O(chunkSize) memory). `@noble/hashes/sha2`
 * provides a streaming API that works in Bun, Node, and browsers without
 * any native bindings.
 */
export class StreamingSha256 {
  private h = sha256.create();
  private finalized = false;

  /** Feed bytes into the hasher. No-op on empty input. */
  update(data: Uint8Array): this {
    if (this.finalized) throw new Error('StreamingSha256: already finalized');
    if (data.length > 0) this.h.update(data);
    return this;
  }

  /**
   * Produce the 32-byte digest. After `digest()` the hasher is finalized;
   * subsequent `update()` calls will throw.
   */
  digest(): Uint8Array {
    this.finalized = true;
    return this.h.digest();
  }

  /** Whether `digest()` has been called. */
  get isFinalized(): boolean {
    return this.finalized;
  }
}

/** Convenience: hash a single buffer in one shot. */
export function sha256Once(data: Uint8Array): Uint8Array {
  return sha256(data);
}
