'use strict';

if (self.importScripts) {
  self.importScripts('/resources/testharness.js');
  self.importScripts('../resources/test-utils.js');
  self.importScripts('../resources/recording-streams.js');
}

test(() => {

  const rs = new ReadableStream();
  const ws = new WritableStream();

  assert_false(rs.locked, 'sanity check: the ReadableStream must not start locked');
  assert_false(ws.locked, 'sanity check: the WritableStream must not start locked');

  rs.pipeTo(ws);

  assert_true(rs.locked, 'the ReadableStream must become locked');
  assert_true(ws.locked, 'the WritableStream must become locked');

}, 'Piping must lock both the ReadableStream and WritableStream');

promise_test(() => {

  const rs = new ReadableStream({
    start(controller) {
      controller.close();
    }
  });
  const ws = new WritableStream();

  return rs.pipeTo(ws).then(() => {
    assert_false(rs.locked, 'the ReadableStream must become unlocked');
    assert_false(ws.locked, 'the WritableStream must become unlocked');
  });

}, 'Piping finishing must unlock both the ReadableStream and WritableStream');

promise_test(t => {

  const fakeRS = Object.create(ReadableStream.prototype);
  const ws = new WritableStream();

  return methodRejects(t, ReadableStream.prototype, 'pipeTo', fakeRS, [ws]);

}, 'pipeTo must check the brand of its ReadableStream this value');

promise_test(t => {

  const rs = new ReadableStream();
  const fakeWS = Object.create(WritableStream.prototype);

  return methodRejects(t, ReadableStream.prototype, 'pipeTo', rs, [fakeWS]);

}, 'pipeTo must check the brand of its WritableStream argument');

promise_test(t => {

  const rs = new ReadableStream();
  const ws = new WritableStream();

  rs.getReader();

  assert_true(rs.locked, 'sanity check: the ReadableStream starts locked');
  assert_false(ws.locked, 'sanity check: the WritableStream does not start locked');

  return promise_rejects(t, new TypeError(), rs.pipeTo(ws)).then(() => {
    assert_false(ws.locked, 'the WritableStream must still be unlocked');
  });

}, 'pipeTo must fail if the ReadableStream is locked, and not lock the WritableStream');

promise_test(t => {

  const rs = new ReadableStream();
  const ws = new WritableStream();

  ws.getWriter();

  assert_false(rs.locked, 'sanity check: the ReadableStream does not start locked');
  assert_true(ws.locked, 'sanity check: the WritableStream starts locked');

  return promise_rejects(t, new TypeError(), rs.pipeTo(ws)).then(() => {
    assert_false(rs.locked, 'the ReadableStream must still be unlocked');
  });

}, 'pipeTo must fail if the WritableStream is locked, and not lock the ReadableStream');

promise_test(() => {

  const CHUNKS = 10;

  const rs = new ReadableStream({
    start(c) {
      for (let i = 0; i < CHUNKS; ++i) {
        c.enqueue(i);
      }
      c.close();
    }
  });

  const written = [];
  const ws = new WritableStream({
    write(chunk) {
      written.push(chunk);
    },
    close() {
      written.push('closed');
    }
  }, new CountQueuingStrategy({ highWaterMark: CHUNKS }));

  return rs.pipeTo(ws).then(() => {
    const targetValues = [];
    for (let i = 0; i < CHUNKS; ++i) {
      targetValues.push(i);
    }
    targetValues.push('closed');

    assert_array_equals(written, targetValues, 'the correct values must be written');

    // Ensure both readable and writable are closed by the time the pipe finishes.
    return Promise.all([
      rs.getReader().closed,
      ws.getWriter().closed
    ]);
  });

  // NOTE: no requirement on *when* the pipe finishes; that is left to implementations.

}, 'Piping from a ReadableStream from which lots of chunks are synchronously readable');

promise_test(() => {

  let controller;
  const rs = recordingReadableStream({
    start(c) {
      controller = c;
    }
  });

  const ws = recordingWritableStream();

  const pipePromise = rs.pipeTo(ws).then(() => {
    assert_array_equals(ws.events, ['write', 'Hello', 'close']);
  });

  setTimeout(() => {
    controller.enqueue('Hello');
    setTimeout(() => controller.close(), 10);
  }, 10);

  return pipePromise;

}, 'Piping from a ReadableStream for which a chunk becomes asynchronously readable after the pipeTo');

for (const preventAbort of [true, false]) {
  promise_test(() => {

    const rs = new ReadableStream({
      pull() {
        return Promise.reject(undefined);
      }
    });

    return rs.pipeTo(new WritableStream(), { preventAbort }).then(
        () => assert_unreached('pipeTo promise should be rejected'),
        value => assert_equals(value, undefined, 'rejection value should be undefined'));

  }, `an undefined rejection from pull should cause pipeTo() to reject when preventAbort is ${preventAbort}`);
}

for (const preventCancel of [true, false]) {
  promise_test(() => {

    const rs = new ReadableStream({
      pull(controller) {
        controller.enqueue(0);
      }
    });

    const ws = new WritableStream({
      write() {
        return Promise.reject(undefined);
      }
    });

    return rs.pipeTo(ws, { preventCancel }).then(
         () => assert_unreached('pipeTo promise should be rejected'),
        value => assert_equals(value, undefined, 'rejection value should be undefined'));

  }, `an undefined rejection from write should cause pipeTo() to reject when preventCancel is ${preventCancel}`);
}

done();
