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

import { DEFAULT_BUFFER_SIZE } from "./_constants.ts";
import type { Reader, ReaderSync } from "./types.ts";

export type { Reader, ReaderSync };

/**
 * Turns a {@linkcode Reader} into an async iterator.
 *
 * @example Usage
 * ```ts no-assert
 * import { iterateReader } from "@std/io/iterate-reader";
 *
 * using file = await Deno.open("README.md");
 * for await (const chunk of iterateReader(file)) {
 *   console.log(chunk);
 * }
 * ```
 *
 * @example Usage with buffer size
 * ```ts no-assert
 * import { iterateReader } from "@std/io/iterate-reader";
 *
 * using file = await Deno.open("README.md");
 * const iter = iterateReader(file, {
 *   bufSize: 1024 * 1024
 * });
 * for await (const chunk of iter) {
 *   console.log(chunk);
 * }
 * ```
 *
 * @param reader The reader to read from
 * @param options The options
 * @param options.bufSize The size of the buffer to use
 * @returns The async iterator of Uint8Array chunks
 */
export async function* iterateReader(
  reader: Reader,
  options?: {
    bufSize?: number;
  },
): AsyncIterableIterator<Uint8Array> {
  const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE;
  const b = new Uint8Array(bufSize);
  while (true) {
    const result = await reader.read(b);
    if (result === null) {
      break;
    }

    yield b.slice(0, result);
  }
}

/**
 * Turns a {@linkcode ReaderSync} into an iterator.
 *
 * @example Usage
 * ```ts
 * import { iterateReaderSync } from "@std/io/iterate-reader";
 * import { assert } from "@std/assert/assert"
 *
 * using file = Deno.openSync("README.md");
 * for (const chunk of iterateReaderSync(file)) {
 *   assert(chunk instanceof Uint8Array);
 * }
 * ```
 *
 * Second argument can be used to tune size of a buffer.
 * Default size of the buffer is 32kB.
 *
 * @example Usage with buffer size
 * ```ts
 * import { iterateReaderSync } from "@std/io/iterate-reader";
 * import { assert } from "@std/assert/assert"
 *
 * using file = await Deno.open("README.md");
 * const iter = iterateReaderSync(file, {
 *   bufSize: 1024 * 1024
 * });
 * for (const chunk of iter) {
 *   assert(chunk instanceof Uint8Array);
 * }
 * ```
 *
 * Iterator uses an internal buffer of fixed size for efficiency; it returns
 * a view on that buffer on each iteration. It is therefore caller's
 * responsibility to copy contents of the buffer if needed; otherwise the
 * next iteration will overwrite contents of previously returned chunk.
 *
 * @param reader The reader to read from
 * @param options The options
 * @returns The iterator of Uint8Array chunks
 */
export function* iterateReaderSync(
  reader: ReaderSync,
  options?: {
    bufSize?: number;
  },
): IterableIterator<Uint8Array> {
  const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE;
  const b = new Uint8Array(bufSize);
  while (true) {
    const result = reader.readSync(b);
    if (result === null) {
      break;
    }

    yield b.slice(0, result);
  }
}

// denoCacheMetadata={"headers":{"x-content-type-options":"nosniff","x-robots-tag":"noindex","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=wu2whAR5QNtmTCPZJJQdjYQ%2BZyxoyEAbTzyZCd5wimuzPzOCou6C24%2F4H5BpXMCGwcQVWkCn17QCN49x48eZM34eIexWL2O0wseVyLUqEegnJi7szCnUHvA%3D\"}]}","etag":"\"56f9e66b7beafc20022baf0a9c47772a\"","access-control-expose-headers":"*","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","set-cookie":"__cf_bm=EcHimTPIzpoajlmy7i6Proj7uMam8lxAGPrDcFw2UBU-1785241875.0326324-1.0.1.1-fUrvODLp6YA2u9dcqV..BJydgEqmdIgvom2Ivmj1hQEMF2vaWMgykK0yduF21DNPls6s15FZR3U6d8gY3DPzqeqKmAYH2G6CteRoVv1AwB2udY8WmojhWtiImEAIvwym; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","access-control-allow-origin":"*","cross-origin-resource-policy":"cross-origin","cf-ray":"a223e656f8647db6-LAX","content-type":"text/typescript","content-length":"3025","date":"Tue, 28 Jul 2026 12:31:15 GMT","vary":"Origin","server":"cloudflare","cache-control":"public, max-age=31536000, immutable","alt-svc":"h3=\":443\"; ma=86400","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}"},"url":"https://jsr.io/@std/io/0.224.8/iterate_reader.ts","time":1785241875}