'use strict';

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

const error1 = new Error('error1');
error1.name = 'error1';

const error2 = new Error('error2');
error2.name = 'error2';

promise_test(() => {
  const ws = new WritableStream({
    close() {
      return 'Hello';
    }
  });

  const writer = ws.getWriter();

  const closePromise = writer.close();
  return closePromise.then(value => assert_equals(value, undefined, 'fulfillment value must be undefined'));
}, 'fulfillment value of ws.close() call must be undefined even if the underlying sink returns a non-undefined ' +
    'value');

promise_test(() => {
  let controller;
  let resolveClose;
  const ws = new WritableStream({
    start(c) {
      controller = c;
    },
    close() {
      return new Promise(resolve => {
        resolveClose = resolve;
      });
    }
  });

  const writer = ws.getWriter();

  const closePromise = writer.close();
  return flushAsyncEvents().then(() => {
    controller.error(error1);
    return flushAsyncEvents();
  }).then(() => {
    resolveClose();
    return Promise.all([
      closePromise,
      writer.closed,
      flushAsyncEvents().then(() => writer.closed)]);
  });
}, 'when sink calls error asynchronously while sink close is in-flight, the stream should not become errored');

promise_test(() => {
  let controller;
  const passedError = new Error('error me');
  const ws = new WritableStream({
    start(c) {
      controller = c;
    },
    close() {
      controller.error(passedError);
    }
  });

  const writer = ws.getWriter();

  return writer.close().then(() => writer.closed);
}, 'when sink calls error synchronously while closing, the stream should not become errored');

promise_test(t => {
  const ws = new WritableStream({
    close() {
      throw error1;
    }
  });

  const writer = ws.getWriter();

  return Promise.all([
    writer.write('y'),
    promise_rejects(t, error1, writer.close(), 'close() must reject with the error'),
    promise_rejects(t, error1, writer.closed, 'closed must reject with the error')
  ]);
}, 'when the sink throws during close, and the close is requested while a write is still in-flight, the stream should ' +
   'become errored during the close');

promise_test(() => {
  const ws = new WritableStream({
    write(chunk, controller) {
      controller.error(error1);
      return new Promise(() => {});
    }
  });

  const writer = ws.getWriter();
  writer.write('a');

  return delay(0).then(() => {
    writer.releaseLock();
  });
}, 'releaseLock on a stream with a pending write in which the stream has been errored');

promise_test(() => {
  let controller;
  const ws = new WritableStream({
    start(c) {
      controller = c;
    },
    close() {
      controller.error(error1);
      return new Promise(() => {});
    }
  });

  const writer = ws.getWriter();
  writer.close();

  return delay(0).then(() => {
    writer.releaseLock();
  });
}, 'releaseLock on a stream with a pending close in which controller.error() was called');

promise_test(() => {
  const ws = recordingWritableStream();

  const writer = ws.getWriter();

  return writer.ready.then(() => {
    assert_equals(writer.desiredSize, 1, 'desiredSize should be 1');

    writer.close();
    assert_equals(writer.desiredSize, 1, 'desiredSize should be still 1');

    return writer.ready.then(v => {
      assert_equals(v, undefined, 'ready promise should be fulfilled with undefined');
      assert_array_equals(ws.events, ['close'], 'write and abort should not be called');
    });
  });
}, 'when close is called on a WritableStream in writable state, ready should return a fulfilled promise');

promise_test(() => {
  const ws = recordingWritableStream({
    write() {
      return new Promise(() => {});
    }
  });

  const writer = ws.getWriter();

  return writer.ready.then(() => {
    writer.write('a');

    assert_equals(writer.desiredSize, 0, 'desiredSize should be 0');

    let calledClose = false;
    return Promise.all([
      writer.ready.then(v => {
        assert_equals(v, undefined, 'ready promise should be fulfilled with undefined');
        assert_true(calledClose, 'ready should not be fulfilled before writer.close() is called');
        assert_array_equals(ws.events, ['write', 'a'], 'sink abort() should not be called');
      }),
      flushAsyncEvents().then(() => {
        writer.close();
        calledClose = true;
      })
    ]);
  });
}, 'when close is called on a WritableStream in waiting state, ready promise should be fulfilled');

promise_test(() => {
  let asyncCloseFinished = false;
  const ws = recordingWritableStream({
    close() {
      return flushAsyncEvents().then(() => {
        asyncCloseFinished = true;
      });
    }
  });

  const writer = ws.getWriter();
  return writer.ready.then(() => {
    writer.write('a');

    writer.close();

    return writer.ready.then(v => {
      assert_false(asyncCloseFinished, 'ready promise should be fulfilled before async close completes');
      assert_equals(v, undefined, 'ready promise should be fulfilled with undefined');
      assert_array_equals(ws.events, ['write', 'a', 'close'], 'sink abort() should not be called');
    });
  });
}, 'when close is called on a WritableStream in waiting state, ready should be fulfilled immediately even if close ' +
    'takes a long time');

promise_test(t => {
  const rejection = { name: 'letter' };
  const ws = new WritableStream({
    close() {
      return {
        then(onFulfilled, onRejected) { onRejected(rejection); }
      };
    }
  });
  return promise_rejects(t, rejection, ws.getWriter().close(), 'close() should return a rejection');
}, 'returning a thenable from close() should work');

promise_test(t => {
  const ws = new WritableStream();
  const writer = ws.getWriter();
  return writer.ready.then(() => {
    const closePromise = writer.close();
    const closedPromise = writer.closed;
    writer.releaseLock();
    return Promise.all([
      closePromise,
      promise_rejects(t, new TypeError(), closedPromise, '.closed promise should be rejected')
    ]);
  });
}, 'releaseLock() should not change the result of sync close()');

promise_test(t => {
  const ws = new WritableStream({
    close() {
      return flushAsyncEvents();
    }
  });
  const writer = ws.getWriter();
  return writer.ready.then(() => {
    const closePromise = writer.close();
    const closedPromise = writer.closed;
    writer.releaseLock();
    return Promise.all([
      closePromise,
      promise_rejects(t, new TypeError(), closedPromise, '.closed promise should be rejected')
    ]);
  });
}, 'releaseLock() should not change the result of async close()');

promise_test(() => {
  let resolveClose;
  const ws = new WritableStream({
    close() {
      const promise = new Promise(resolve => {
        resolveClose = resolve;
      });
      return promise;
    }
  });
  const writer = ws.getWriter();
  const closePromise = writer.close();
  writer.releaseLock();
  return delay(0).then(() => {
    resolveClose();
    return closePromise.then(() => {
      assert_equals(ws.getWriter().desiredSize, 0, 'desiredSize should be 0');
    });
  });
}, 'close() should set state to CLOSED even if writer has detached');

promise_test(() => {
  let resolveClose;
  const ws = new WritableStream({
    close() {
      const promise = new Promise(resolve => {
        resolveClose = resolve;
      });
      return promise;
    }
  });
  const writer = ws.getWriter();
  writer.close();
  writer.releaseLock();
  return delay(0).then(() => {
    const abortingWriter = ws.getWriter();
    const abortPromise = abortingWriter.abort();
    abortingWriter.releaseLock();
    resolveClose();
    return abortPromise;
  });
}, 'the promise returned by async abort during close should resolve');

// Though the order in which the promises are fulfilled or rejected is arbitrary, we're checking it for
// interoperability. We can change the order as long as we file bugs on all implementers to update to the latest tests
// to keep them interoperable.

promise_test(() => {
  const ws = new WritableStream({});

  const writer = ws.getWriter();

  const closePromise = writer.close();

  const events = [];
  return Promise.all([
    closePromise.then(() => {
      events.push('closePromise');
    }),
    writer.closed.then(() => {
      events.push('closed');
    })
  ]).then(() => {
    assert_array_equals(events, ['closePromise', 'closed'],
                        'promises must fulfill/reject in the expected order');
  });
}, 'promises must fulfill/reject in the expected order on closure');

promise_test(() => {
  const ws = new WritableStream({});

  // Wait until the WritableStream starts so that the close() call gets processed. Otherwise, abort() will be
  // processed without waiting for completion of the close().
  return delay(0).then(() => {
    const writer = ws.getWriter();

    const closePromise = writer.close();
    const abortPromise = writer.abort(error1);

    const events = [];
    return Promise.all([
      closePromise.then(() => {
        events.push('closePromise');
      }),
      abortPromise.then(() => {
        events.push('abortPromise');
      }),
      writer.closed.then(() => {
        events.push('closed');
      })
    ]).then(() => {
      assert_array_equals(events, ['closePromise', 'abortPromise', 'closed'],
                          'promises must fulfill/reject in the expected order');
    });
  });
}, 'promises must fulfill/reject in the expected order on aborted closure');

promise_test(t => {
  const ws = new WritableStream({
    close() {
      return Promise.reject(error1);
    }
  });

  // Wait until the WritableStream starts so that the close() call gets processed.
  return delay(0).then(() => {
    const writer = ws.getWriter();

    const closePromise = writer.close();
    const abortPromise = writer.abort(error2);

    const events = [];
    closePromise.catch(() => events.push('closePromise'));
    abortPromise.catch(() => events.push('abortPromise'));
    writer.closed.catch(() => events.push('closed'));
    return Promise.all([
      promise_rejects(t, error1, closePromise,
                      'closePromise must reject with the error returned from the sink\'s close method'),
      promise_rejects(t, error1, abortPromise,
                      'abortPromise must reject with the error returned from the sink\'s close method'),
      promise_rejects(t, new TypeError(), writer.closed,
                      'writer.closed must reject with a TypeError indicating the stream was aborted')
    ]).then(() => {
      assert_array_equals(events, ['closePromise', 'abortPromise', 'closed'],
                          'promises must fulfill/reject in the expected order');
    });
  });
}, 'promises must fulfill/reject in the expected order on aborted and errored closure');

promise_test(t => {
  let resolveWrite;
  let controller;
  const ws = new WritableStream({
    write(chunk, c) {
      controller = c;
      return new Promise(resolve => {
        resolveWrite = resolve;
      });
    }
  });
  const writer = ws.getWriter();
  return writer.ready.then(() => {
    const writePromise = writer.write('c');
    controller.error(error1);
    const closePromise = writer.close();
    let closeRejected = false;
    closePromise.catch(() => {
      closeRejected = true;
    });
    return flushAsyncEvents().then(() => {
      assert_false(closeRejected);
      resolveWrite();
      return Promise.all([
        writePromise,
        promise_rejects(t, error1, closePromise, 'close() should reject')
      ]).then(() => {
        assert_true(closeRejected);
      });
    });
  });
}, 'close() should not reject until no sink methods are in flight');

done();
