// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.

import type { Reader } from "./types.ts";

/**
 * Reader utility for combining multiple readers.
 *
 * @example Usage
 * ```ts
 * import { MultiReader } from "@std/io/multi-reader";
 * import { StringReader } from "@std/io/string-reader";
 * import { readAll } from "@std/io/read-all";
 * import { assertEquals } from "@std/assert/equals";
 *
 * const r1 = new StringReader("hello");
 * const r2 = new StringReader("world");
 * const mr = new MultiReader([r1, r2]);
 *
 * const res = await readAll(mr);
 *
 * assertEquals(new TextDecoder().decode(res), "helloworld");
 * ```
 *
 * @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
 */
export class MultiReader implements Reader {
  readonly #readers: Reader[];
  #currentIndex = 0;

  /**
   * Construct a new instance.
   *
   * @param readers The readers to combine.
   */
  constructor(readers: Reader[]) {
    this.#readers = [...readers];
  }

  /**
   * Reads data from the readers.
   *
   * @example Usage
   * ```ts
   * import { MultiReader } from "@std/io/multi-reader";
   * import { StringReader } from "@std/io/string-reader";
   * import { readAll } from "@std/io/read-all";
   * import { assertEquals } from "@std/assert/equals";
   *
   * const r1 = new StringReader("hello");
   * const r2 = new StringReader("world");
   * const mr = new MultiReader([r1, r2]);
   *
   * const data = new Uint8Array(5);
   * const res = await mr.read(data);
   *
   * assertEquals(res, 5);
   * assertEquals(new TextDecoder().decode(data), "hello");
   *
   * const res2 = await mr.read(data);
   * assertEquals(res2, 0);
   *
   * const res3 = await mr.read(data);
   * assertEquals(res3, 5);
   * assertEquals(new TextDecoder().decode(data), "world");
   * ```
   *
   * @param p The buffer to read data into.
   * @returns The number of bytes read.
   */
  async read(p: Uint8Array): Promise<number | null> {
    const r = this.#readers[this.#currentIndex];
    if (!r) return null;
    const result = await r.read(p);
    if (result === null) {
      this.#currentIndex++;
      return 0;
    }
    return result;
  }
}

// denoCacheMetadata={"headers":{"etag":"\"a29c368b387e47229580a5c35c7ea4de\"","date":"Tue, 28 Jul 2026 12:31:15 GMT","x-content-type-options":"nosniff","cache-control":"public, max-age=31536000, immutable","access-control-allow-origin":"*","x-jsr-backend":"modules","content-type":"text/typescript","cross-origin-resource-policy":"cross-origin","set-cookie":"__cf_bm=f2H2dZGev_zsS5IgyqKcpN2IGzdtTQ29jAbt4mWbfqQ-1785241875.0337598-1.0.1.1-9zLvuqkrO7wcyEVy1eLHKqOjAPtll7terPHcz7lttRIXbynx1ShovTT8oMVesyyr3Qg1EsK067VPLjT92mOenNsBG6rKtLtZXu.ok0M.8a2alyOh7TAMChyzZoZ.pDyt; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","vary":"Origin","content-security-policy":"default-src 'none'; script-src 'none'; style-src 'none'; img-src 'none'; font-src 'none'; connect-src 'none'; frame-src 'none'; object-src 'none'; frame-ancestors 'none'; sandbox; form-action 'none';","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=qObXZTXqx5qPgw7TTQfx8wM6JpaMGf8mRHocynP7IAQiWpFyHSnHBro6RWSyzl6vVNzWXpPCzlh0fYckMvWSkc65SwvtGTZgOOMwFLipM0fbwpKuEsxPvmI%3D\"}]}","server":"cloudflare","access-control-expose-headers":"*","x-robots-tag":"noindex","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","content-length":"2287","alt-svc":"h3=\":443\"; ma=86400","cf-ray":"a223e656f8697db6-LAX"},"url":"https://jsr.io/@std/io/0.224.8/multi_reader.ts","time":1785241875}