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

import { Buffer } from "jsr:/@std/io@^0.224.1/buffer";
import { writeAll } from "jsr:/@std/io@^0.224.1/write-all";
import type { Reader } from "jsr:/@std/io@^0.224.1/types";

/**
 * Create a {@linkcode https://jsr.io/@std/io/doc/types/~/Reader | Reader} from an iterable of {@linkcode Uint8Array}s.
 *
 * @param iterable An iterable or async iterable of `Uint8Array`s to convert into a `Reader`.
 * @returns A `Reader` that reads from the iterable.
 *
 * @example Write `Deno.build` information to the blackhole 3 times every second
 * ```ts no-eval no-assert
 * import { readerFromIterable } from "@std/streams/reader-from-iterable";
 * import { copy } from "@std/io/copy";
 * import { delay } from "@std/async/delay";
 * import { devNull } from "node:os";
 *
 * const reader = readerFromIterable((async function* () {
 *   for (let i = 0; i < 3; i++) {
 *     await delay(1000);
 *     const message = `data: ${JSON.stringify(Deno.build)}\n\n`;
 *     yield new TextEncoder().encode(message);
 *   }
 * })());
 *
 * using blackhole = await Deno.open(devNull, { write: true });
 * await copy(reader, blackhole);
 * ```
 *
 * @deprecated This will be removed in 1.0.0. Use {@linkcode ReadableStream.from} instead.
 */
export function readerFromIterable(
  iterable: Iterable<Uint8Array> | AsyncIterable<Uint8Array>,
): Reader {
  const iterator: Iterator<Uint8Array> | AsyncIterator<Uint8Array> =
    (iterable as AsyncIterable<Uint8Array>)[Symbol.asyncIterator]?.() ??
      (iterable as Iterable<Uint8Array>)[Symbol.iterator]?.();
  const buffer = new Buffer();
  return {
    async read(p: Uint8Array): Promise<number | null> {
      if (buffer.length === 0) {
        const result = await iterator.next();
        if (result.done) {
          return null;
        } else {
          if (result.value.byteLength <= p.byteLength) {
            p.set(result.value);
            return result.value.byteLength;
          }
          p.set(result.value.subarray(0, p.byteLength));
          await writeAll(buffer, result.value.subarray(p.byteLength));
          return p.byteLength;
        }
      } else {
        const n = await buffer.read(p);
        if (n === null) {
          return this.read(p);
        }
        return n;
      }
    },
  };
}

// denoCacheMetadata={"headers":{"etag":"\"8fd825cb25df222e0971c1d501ca92e9\"","set-cookie":"__cf_bm=dJ.Vwk28DRNkY1i7W5pf7v_rJ8uLJrCaFCi23I3i09c-1785241875.1812005-1.0.1.1-6NSqTCA9.DsSzO_f4C8XV2Y3MXQx_bhy61i32J4mESlCOye9nr1ANrEM0dSYs0iIpWlTZFsrBvK1ntCqhp5zPc762VsEuZmodi4RRnqd7MqfCQ2djf8tHE9S4n9es4Qx; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","cache-control":"public, max-age=31536000, immutable","access-control-expose-headers":"*","x-robots-tag":"noindex","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=cG%2FtsmsNmTx5sqgoxurqtLwbuBYrlLOlWT%2Bx2RsfvtunSuPJj%2FUW28tO8LqU1YE0%2BWj6qzI7lPdc7L%2BmDqqNhusrh0RJ14ZcB56SAAEQZTULUnskCrD3LPg%3D\"}]}","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';","x-jsr-backend":"modules","content-type":"text/typescript","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","server":"cloudflare","vary":"Origin","cross-origin-resource-policy":"cross-origin","cf-ray":"a223e657dabf7db6-LAX","content-length":"2368","x-content-type-options":"nosniff","alt-svc":"h3=\":443\"; ma=86400","date":"Tue, 28 Jul 2026 12:31:15 GMT","cf-cache-status":"HIT","accept-ranges":"bytes","age":"112265","access-control-allow-origin":"*"},"url":"https://jsr.io/@std/streams/0.224.5/reader_from_iterable.ts","time":1785241875}