'use strict';

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

let ReadableStreamReader;

test(() => {

  // It's not exposed globally, but we test a few of its properties here.
  ReadableStreamReader = (new ReadableStream()).getReader().constructor;

}, 'Can get the ReadableStreamReader constructor indirectly');

test(() => {

  assert_throws(new TypeError(), () => new ReadableStreamReader('potato'));
  assert_throws(new TypeError(), () => new ReadableStreamReader({}));
  assert_throws(new TypeError(), () => new ReadableStreamReader());

}, 'ReadableStreamReader constructor should get a ReadableStream object as argument');

test(() => {

  const methods = ['cancel', 'constructor', 'read', 'releaseLock'];
  const properties = methods.concat(['closed']).sort();

  const rsReader = new ReadableStreamReader(new ReadableStream());
  const proto = Object.getPrototypeOf(rsReader);

  assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties);

  for (const m of methods) {
    const propDesc = Object.getOwnPropertyDescriptor(proto, m);
    assert_equals(propDesc.enumerable, false, 'method should be non-enumerable');
    assert_equals(propDesc.configurable, true, 'method should be configurable');
    assert_equals(propDesc.writable, true, 'method should be writable');
    assert_equals(typeof rsReader[m], 'function', 'should have be a method');
  }

  const closedPropDesc = Object.getOwnPropertyDescriptor(proto, 'closed');
  assert_equals(closedPropDesc.enumerable, false, 'closed should be non-enumerable');
  assert_equals(closedPropDesc.configurable, true, 'closed should be configurable');
  assert_not_equals(closedPropDesc.get, undefined, 'closed should have a getter');
  assert_equals(closedPropDesc.set, undefined, 'closed should not have a setter');

  assert_equals(rsReader.cancel.length, 1, 'cancel has 1 parameter');
  assert_not_equals(rsReader.closed, undefined, 'has a non-undefined closed property');
  assert_equals(typeof rsReader.closed.then, 'function', 'closed property is thenable');
  assert_equals(typeof rsReader.constructor, 'function', 'has a constructor method');
  assert_equals(rsReader.constructor.length, 1, 'constructor has 1 parameter');
  assert_equals(typeof rsReader.read, 'function', 'has a getReader method');
  assert_equals(rsReader.read.length, 0, 'read has no parameters');
  assert_equals(typeof rsReader.releaseLock, 'function', 'has a releaseLock method');
  assert_equals(rsReader.releaseLock.length, 0, 'releaseLock has no parameters');

}, 'ReadableStreamReader instances should have the correct list of properties');

test(() => {

  const rsReader = new ReadableStreamReader(new ReadableStream());
  assert_equals(rsReader.closed, rsReader.closed, 'closed should return the same promise');

}, 'ReadableStreamReader closed should always return the same promise object');

test(() => {

  const rs = new ReadableStream();
  new ReadableStreamReader(rs); // Constructing directly the first time should be fine.
  assert_throws(new TypeError(), () => new ReadableStreamReader(rs),
                'constructing directly the second time should fail');

}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct ' +
   'construction)');

test(() => {

  const rs = new ReadableStream();
  new ReadableStreamReader(rs); // Constructing directly should be fine.
  assert_throws(new TypeError(), () => rs.getReader(), 'getReader() should fail');

}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct ' +
   'construction)');

test(() => {

  const rs = new ReadableStream();
  rs.getReader(); // getReader() should be fine.
  assert_throws(new TypeError(), () => new ReadableStreamReader(rs), 'constructing directly should fail');

}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader)');

test(() => {

  const rs = new ReadableStream();
  rs.getReader(); // getReader() should be fine.
  assert_throws(new TypeError(), () => rs.getReader(), 'getReader() should fail');

}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader)');

test(() => {

  const rs = new ReadableStream({
    start(c) {
      c.close();
    }
  });

  new ReadableStreamReader(rs); // Constructing directly should not throw.

}, 'Constructing a ReadableStreamReader directly should be OK if the stream is closed');

test(() => {

  const theError = new Error('don\'t say i didn\'t warn ya');
  const rs = new ReadableStream({
    start(c) {
      c.error(theError);
    }
  });

  new ReadableStreamReader(rs); // Constructing directly should not throw.

}, 'Constructing a ReadableStreamReader directly should be OK if the stream is errored');

promise_test(() => {

  let controller;
  const rs = new ReadableStream({
    start(c) {
      controller = c;
    }
  });
  const reader = rs.getReader();

  const promise = reader.read().then(result => {
    assert_object_equals(result, { value: 'a', done: false }, 'read() should fulfill with the enqueued chunk');
  });

  controller.enqueue('a');
  return promise;

}, 'Reading from a reader for an empty stream will wait until a chunk is available');

promise_test(() => {

  let cancelCalled = false;
  const passedReason = new Error('it wasn\'t the right time, sorry');
  const rs = new ReadableStream({
    cancel(reason) {
      assert_true(rs.locked, 'the stream should still be locked');
      assert_throws(new TypeError(), () => rs.getReader(), 'should not be able to get another reader');
      assert_equals(reason, passedReason, 'the cancellation reason is passed through to the underlying source');
      cancelCalled = true;
    }
  });

  const reader = rs.getReader();
  return reader.cancel(passedReason).then(() => assert_true(cancelCalled));

}, 'cancel() on a reader does not release the reader');

promise_test(() => {

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

  const reader = rs.getReader();
  const promise = reader.closed;

  controller.close();
  return promise;

}, 'closed should be fulfilled after stream is closed (.closed access before acquiring)');

promise_test(t => {

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

  const reader1 = rs.getReader();

  reader1.releaseLock();

  const reader2 = rs.getReader();
  controller.close();

  return Promise.all([
    promise_rejects(t, new TypeError(), reader1.closed),
    reader2.closed
  ]);

}, 'closed should be rejected after reader releases its lock (multiple stream locks)');

promise_test(() => {

  const rs = new ReadableStream({
    start(c) {
      c.enqueue('a');
      c.enqueue('b');
      c.close();
    }
  });

  const reader1 = rs.getReader();
  const promise1 = reader1.read().then(r => {
    assert_object_equals(r, { value: 'a', done: false }, 'reading the first chunk from reader1 works');
  });
  reader1.releaseLock();

  const reader2 = rs.getReader();
  const promise2 = reader2.read().then(r => {
    assert_object_equals(r, { value: 'b', done: false }, 'reading the second chunk from reader2 works');
  });
  reader2.releaseLock();

  return Promise.all([promise1, promise2]);

}, 'Multiple readers can access the stream in sequence');

promise_test(() => {
  const rs = new ReadableStream({
    start(c) {
      c.enqueue('a');
    }
  });

  const reader1 = rs.getReader();
  reader1.releaseLock();

  const reader2 = rs.getReader();

  // Should be a no-op
  reader1.releaseLock();

  return reader2.read().then(result => {
    assert_object_equals(result, { value: 'a', done: false },
                         'read() should still work on reader2 even after reader1 is released');
  });

}, 'Cannot use an already-released reader to unlock a stream again');

promise_test(t => {

  const rs = new ReadableStream({
    start(c) {
      c.enqueue('a');
    },
    cancel() {
      assert_unreached('underlying source cancel should not be called');
    }
  });

  const reader = rs.getReader();
  reader.releaseLock();
  const cancelPromise = reader.cancel();

  const reader2 = rs.getReader();
  const readPromise = reader2.read().then(r => {
    assert_object_equals(r, { value: 'a', done: false }, 'a new reader should be able to read a chunk');
  });

  return Promise.all([
    promise_rejects(t, new TypeError(), cancelPromise),
    readPromise
  ]);

}, 'cancel() on a released reader is a no-op and does not pass through');

promise_test(t => {

  const promiseAsserts = [];

  let controller;
  const theError = { name: 'unique error' };
  const rs = new ReadableStream({
    start(c) {
      controller = c;
    }
  });

  const reader1 = rs.getReader();

  promiseAsserts.push(
    promise_rejects(t, theError, reader1.closed),
    promise_rejects(t, theError, reader1.read())
  );

  assert_throws(new TypeError(), () => rs.getReader(), 'trying to get another reader before erroring should throw');

  controller.error(theError);

  reader1.releaseLock();

  const reader2 = rs.getReader();

  promiseAsserts.push(
    promise_rejects(t, theError, reader2.closed),
    promise_rejects(t, theError, reader2.read())
  );

  return Promise.all(promiseAsserts);

}, 'Getting a second reader after erroring the stream and releasing the reader should succeed');

promise_test(t => {

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

  const promise = rs.getReader().closed.then(
    t.unreached_func('closed promise should not be fulfilled when stream is errored'),
    err => {
      assert_equals(err, undefined, 'passed error should be undefined as it was');
    }
  );

  controller.error();
  return promise;

}, 'ReadableStreamReader closed promise should be rejected with undefined if that is the error');


promise_test(t => {

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

  return rs.getReader().read().then(
    t.unreached_func('read promise should not be fulfilled when stream is errored'),
    err => {
      assert_equals(err, undefined, 'passed error should be undefined as it was');
    }
  );

}, 'ReadableStreamReader: if start rejects with no parameter, it should error the stream with an undefined error');

promise_test(t => {

  const theError = { name: 'unique string' };
  let controller;
  const rs = new ReadableStream({
    start(c) {
      controller = c;
    }
  });

  const promise = promise_rejects(t, theError, rs.getReader().closed);

  controller.error(theError);
  return promise;

}, 'Erroring a ReadableStream after checking closed should reject ReadableStreamReader closed promise');

promise_test(t => {

  const theError = { name: 'unique string' };
  let controller;
  const rs = new ReadableStream({
    start(c) {
      controller = c;
    }
  });

  controller.error(theError);

  // Let's call getReader twice for extra test coverage of this code path.
  rs.getReader().releaseLock();

  return promise_rejects(t, theError, rs.getReader().closed);

}, 'Erroring a ReadableStream before checking closed should reject ReadableStreamReader closed promise');

promise_test(() => {

  let controller;
  const rs = new ReadableStream({
    start(c) {
      controller = c;
    }
  });
  const reader = rs.getReader();

  const promise = Promise.all([
    reader.read().then(result => {
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
    }),
    reader.read().then(result => {
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
    }),
    reader.closed
  ]);

  controller.close();
  return promise;

}, 'Reading twice on a stream that gets closed');

promise_test(() => {

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

  controller.close();
  const reader = rs.getReader();

  return Promise.all([
    reader.read().then(result => {
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
    }),
    reader.read().then(result => {
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
    }),
    reader.closed
  ]);

}, 'Reading twice on a closed stream');

promise_test(t => {

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

  const myError = { name: 'mashed potatoes' };
  controller.error(myError);

  const reader = rs.getReader();

  return Promise.all([
    promise_rejects(t, myError, reader.read()),
    promise_rejects(t, myError, reader.read()),
    promise_rejects(t, myError, reader.closed)
  ]);

}, 'Reading twice on an errored stream');

promise_test(t => {

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

  const myError = { name: 'mashed potatoes' };
  const reader = rs.getReader();

  const promise = Promise.all([
    promise_rejects(t, myError, reader.read()),
    promise_rejects(t, myError, reader.read()),
    promise_rejects(t, myError, reader.closed)
  ]);

  controller.error(myError);
  return promise;

}, 'Reading twice on a stream that gets errored');

done();
