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

import { writeAll } from "./write_all.ts";
import type { Writer } from "./types.ts";
import { isCloser } from "./_common.ts";

/** Options for {@linkcode toWritableStream}. */
export interface toWritableStreamOptions {
  /**
   * If the `writer` is also a `Closer`, automatically close the `writer`
   * when the stream is closed, aborted, or a write error occurs.
   *
   * @default {true}
   */
  autoClose?: boolean;
}

/**
 * Create a {@linkcode WritableStream} from a {@linkcode Writer}.
 *
 * @example Usage
 * ```ts no-assert
 * import { toWritableStream } from "@std/io/to-writable-stream";
 *
 * await ReadableStream.from(["Hello World"])
 *   .pipeThrough(new TextEncoderStream())
 *   .pipeTo(toWritableStream(Deno.stdout));
 * ```
 *
 * @param writer The writer to write to
 * @param options The options
 * @returns The writable stream
 */
export function toWritableStream(
  writer: Writer,
  options?: toWritableStreamOptions,
): WritableStream<Uint8Array> {
  const { autoClose = true } = options ?? {};

  return new WritableStream({
    async write(chunk, controller) {
      try {
        await writeAll(writer, chunk);
      } catch (e) {
        controller.error(e);
        if (isCloser(writer) && autoClose) {
          writer.close();
        }
      }
    },
    close() {
      if (isCloser(writer) && autoClose) {
        writer.close();
      }
    },
    abort() {
      if (isCloser(writer) && autoClose) {
        writer.close();
      }
    },
  });
}

// denoCacheMetadata={"headers":{"access-control-expose-headers":"*","etag":"\"9d7ba57e5fa2f2de32b8a61a0de79af6\"","server":"cloudflare","content-length":"1597","vary":"Origin","nel":"{\"report_to\":\"cf-nel\",\"success_fraction\":0.0,\"max_age\":604800}","cross-origin-resource-policy":"cross-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';","access-control-allow-origin":"*","content-type":"text/typescript","cf-ray":"a223e65728e87db6-LAX","date":"Tue, 28 Jul 2026 12:31:15 GMT","x-content-type-options":"nosniff","x-jsr-backend":"modules","x-robots-tag":"noindex","set-cookie":"__cf_bm=ZxJiSg1tERcs6xZRVLb7q2yZ52rC0lP3m4cXnmlpl.Y-1785241875.0658345-1.0.1.1-LaLl18aoazovVn3poXGQ5Eb64Oe4cxIAylHv2ztud4EqYVJKNPsbQMm8wHaKQhSTZDaiMQhPTCRe91wOVKNDTx8nWDXPm9HpOtzePUOwggkX1B86j5l3Fz9QeBCcfk1E; HttpOnly; SameSite=None; Secure; Path=/; Domain=jsr.io; Expires=Tue, 28 Jul 2026 13:01:15 GMT","report-to":"{\"group\":\"cf-nel\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://a.nel.cloudflare.com/report/v4?s=LHlvV6%2BxZYCX34KbW6VMwqSBw49Vn1%2FVM9um9vFj0dvvPc3h3hXFxj29aC83WYreAoIbsrWUpgxQ1fNz9lkdPGLFa63wG%2BYirvUVx59AG%2Bv39Yei6ap3wRo%3D\"}]}","alt-svc":"h3=\":443\"; ma=86400","cache-control":"public, max-age=31536000, immutable"},"url":"https://jsr.io/@std/io/0.224.8/to_writable_stream.ts","time":1785241875}