// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax

let testFailed = false;
let testFailure;

function assertThrowsAsync(run, errorType, message) {
  var actual;
  var hadValue = false;
  var hadError = false;
  var promise = run();

  if (typeof promise !== "object" || typeof promise.then !== "function") {
    throw new MjsUnitAssertionError(
        "Expected " + run.toString() +
        " to return a Promise, but it returned " + PrettyPrint(promise));
  }

  promise.then(function(value) { hadValue = true; actual = value; },
               function(error) { hadError = true; actual = error; });

  assertFalse(hadValue || hadError);

  %PerformMicrotaskCheckpoint();

  if (!hadError) {
    throw new MjsUnitAssertionError(
        "Expected " + run + "() to throw " + errorType.name +
        ", but did not throw.");
  }
  if (!(actual instanceof errorType))
    throw new MjsUnitAssertionError(
        "Expected " + run + "() to throw " + errorType.name +
        ", but threw '" + actual + "'");
  if (message !== void 0 && actual.message !== message)
    throw new MjsUnitAssertionError(
        "Expected " + run + "() to throw '" + message + "', but threw '" +
        actual.message + "'");
};

function resolveLater(value) {
  return new Promise(function(resolve) {
    Promise.resolve().then(function() {
      resolve(value);
    });
  });
}

function rejectLater(value) {
  return new Promise(function(resolve, reject) {
    Promise.resolve().then(function() {
      reject(value);
    });
  });
}

const kNext = 1;
const kThrow = 2;
const kReturn = 4;
const kNextThrows = kNext | 8;
const kReturnThrows = kReturn | 16;
const kThrowNormal = kThrow | 32;
const kNextUnchanged = kNext | 64;
const kReturnUnchanged = kReturn | 128;
const kThrowUnchanged = kThrow | 256;
function sync(array, features, log) {
  // `log` is a required parameter
  if (log === void 0) %AbortJS("`log` is undefined");

  let i = 0;
  let methods = {
    next(sent) {
      let done = i >= array.length;
      let value = array[i];
      log.push({ method: "next", sent, value, done });
      if ((features & kNextThrows) === kNextThrows) throw sent;
      if ((features & kNextUnchanged) === kNextUnchanged) return sent;
      i++;
      return { value, done };
    },
    throw(sent) {
      let done = i >= array.length;
      log.push({ method: "throw", sent, done });
      if ((features & kThrowNormal) === kThrowNormal)
          return { value: sent, done };
      if ((features & kThrowUnchanged) === kThrowUnchanged) return sent;
      throw sent;
    },
    return(sent) {
      let done = true;
      log.push({ method: "return", sent, done });
      if ((features & kReturnThrows) === kReturnThrows) throw sent;
      if ((features & kReturnUnchanged) === kReturnUnchanged) return sent;
      return { value: sent, done };
    }
  };
  return {
    [Symbol.iterator]() { return this; },
    next: (features & kNext) ? methods.next : undefined,
    throw: (features & kThrow) ? methods.throw : undefined,
    return: (features & kReturn) ? methods.return : undefined
  };
}

class MyError extends Error {};

(async function AsyncFromSyncWithGenerator() {
  function* gen() {
    yield "sync value";
    try {
      yield new Promise(function(resolve) {
        resolve("async value");
      });
    } catch (error) {
      throw error;
    }
    assertUnreachable("generator is closed");
  }
  let iter = %CreateAsyncFromSyncIterator(gen());

  // [Async-from-Sync Iterator] wraps sync iterator values in a Promise
  let promise = iter.next();
  assertInstanceof(promise, Promise);
  let iter_result = await promise;
  assertEquals({ value: "sync value", done: false }, iter_result);

  // [Async-from-Sync Iterator] will wait for resolution of Promise values
  promise = iter.next();
  assertInstanceof(promise, Promise);
  iter_result = await promise;
  assertEquals({ value: "async value", done: false }, iter_result);

  // [Async-from-Sync Iterator].throw delegates to .throw() method of sync
  // iterator.
  promise = iter.throw(new MyError("Error#1"));
  assertInstanceof(promise, Promise);
  try {
    await promise;
    assertUnreachable("promise should be rejected");
  } catch (e) {
    // If assertUnreachable failed, rethrow
    if (e instanceof MjsUnitAssertionError) throw e;
    assertInstanceof(e, MyError);
    assertEquals("Error#1", e.message);
  }

  // Generator is closed, subsequent calls to .next() will not resume.
  promise = iter.next("floof");
  iter_result = await promise;
  assertEquals({ value: undefined, done: true }, iter_result);

  promise = iter.return("generator closed");
  assertInstanceof(promise, Promise);
  iter_result = await promise;
  assertEquals({ value: "generator closed", done: true }, iter_result);

  // .next(), .return() and .throw() delegate to sync iterator methods, without
  // keeping track of the state of the generator.
  promise = iter.next("unused");
  assertInstanceof(promise, Promise);
  iter_result = await promise;
  assertEquals({ value: undefined, done: true }, iter_result);

  promise = iter.throw(new MyError("Error#2"));
  assertInstanceof(promise, Promise);
  try {
    await promise;
    assertUnreachable("promise should be rejected");
  } catch (e) {
    // If assertUnreachable failed, rethrow
    if (e instanceof MjsUnitAssertionError) throw e;
    assertInstanceof(e, MyError);
    assertEquals("Error#2", e.message);
  }

  promise = iter.return("return-after-completed");
  assertInstanceof(promise, Promise);
  iter_result = await promise;
  assertEquals({ value: "return-after-completed", done: true }, iter_result);
})().catch(function(error) {
  testFailed = true;
  testFailure = error;
});

%PerformMicrotaskCheckpoint();
if (testFailed) {
  throw testFailure;
}


(async function AsyncFromSyncOrderOfOperations() {
  let log = [];
  iter = %CreateAsyncFromSyncIterator(sync(["sync-value"], 0, log));

  try {
    await iter.next();
    assertUnreachable("Iterator.next() method is not optional");
  } catch (e) {
    assertInstanceof(e, TypeError);
    assertEquals([], log);
  }

  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(["sync-value"], kNext, log));
  assertEquals({ value: "sync-value", done: false }, await iter.next("a"));
  assertEquals([
    {
      method: "next",
      sent: "a",
      value: "sync-value",
      done: false
    }
  ], log);

  log = [];
  let asyncValue = resolveLater("async-value");
  iter = %CreateAsyncFromSyncIterator(sync([asyncValue], kNext, log));
  assertEquals({ value: "async-value", done: false }, await iter.next("b"));
  assertEquals([
    {
      method: "next",
      sent: "b",
      value: asyncValue,
      done: false
    }
  ], log);

  // If [sync_iterator].next() produces a rejected Promise or an exception is
  // thrown, Promise is rejected with thrown/rejected value.
  log = [];
  asyncValue = rejectLater("Boo!");
  iter = %CreateAsyncFromSyncIterator(sync([asyncValue], kNext, log));
  try {
    await iter.next('c');
    assertUnreachable('Expected `iter.next(\'c\') to throw, but did not throw');
  } catch (e) {
    assertEquals("Boo!", e);
    assertEquals([
      {
        method: 'next',
        sent: 'c',
        value: asyncValue,
        done: false
      }
    ], log);
  }

  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNextThrows, log));
  try {
    await iter.next('Boo!');
    assertUnreachable('Expected `iter.next(\'c\') to throw, but did not throw');
  } catch (e) {
    assertEquals("Boo!", e);
    assertEquals([
      {
        method: 'next',
        sent: 'Boo!',
        value: 'sync-value',
        done: false
      }
    ], log);
  }


  // [Async-from-Sync Iterator].next() will be rejected with a TypeError if
  // Type([sync_iterator].next()) is not Object.
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNextUnchanged,
                                      log));
  try {
    await iter.next('not-a-JSReceiver');
    assertUnreachable('Expected `iter.next(\'not-a-JSReceiver\')` to ' +
                      'throw, but did not throw')
  } catch (e) {
    assertEquals(e.constructor, TypeError);
  }

  assertEquals([
    {
      method: 'next',
      sent: 'not-a-JSReceiver',
      value: 'sync-value',
      done: false
    }
  ], log);

  // If [sync_iterator] does not have a .return() method, return a Promise
  // resolved with the value `{ value: <<sent value>>, done: true }`.
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-return'], kNext, log));
  assertEquals({
    value: 'd',
    done: true
  }, await iter.return('d'));

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({
    value: 'sync-return',
    done: false
  }, await iter.next('e'));

  assertEquals([
    {
      method: 'next',
      sent: 'e',
      value: 'sync-return',
      done: false
    }
  ], log);

  // If [sync_iterator] does have a .return() method, return a Promise
  // fulfilled with the iterator result of [sync_iterator].return().
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-return'],
                                      kNext|kReturn, log));
  assertEquals({
    value: 'f',
    done: true
  }, await iter.return('f'));

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({
    value: 'sync-return',
    done: false
  }, await iter.next('g'));

  assertEquals([
    {
      method: 'return',
      sent: 'f',
      done: true
    },
    {
      method: 'next',
      sent: 'g',
      value: 'sync-return',
      done: false
    }
  ], log);

  // If [sync_iterator].return() produces a rejected Promise or an exception is
  // thrown, Promise is rejected with thrown/rejected value.
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kReturnThrows,
                                      log));
  try {
    await iter.return('Boo!!');
    assertUnreachable('Expected `iter.return(\'Boo!!\')` to throw, but did ' +
                      'not throw');
  } catch (e) {
    assertEquals("Boo!!", e);
  }

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({ value: 'sync-value', done: false }, await iter.next('h'));
  assertEquals([
    {
      method: 'return',
      sent: 'Boo!!',
      done: true
    },
    {
      method: 'next',
      sent: 'h',
      value: 'sync-value',
      done: false
    }
  ], log);


  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kReturn, log));

  let rejection = Promise.reject('Boo!!');
  try {
    await iter.return(rejection);
    assertUnreachable('Expected `iter.return(Promise.reject(\'Boo!!\'))` to ' +
                      'throw, but did not throw');
  } catch (e) {
    assertEquals('Boo!!', e);
  }

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({ value: 'sync-value', done: false }, await iter.next('i'));
  assertEquals([
    {
      method: 'return',
      sent: rejection,
      done: true
    },
    {
      method: 'next',
      sent: 'i',
      value: 'sync-value',
      done: false
    }
  ], log);

  // [Async-from-Sync Iterator].return() will be rejected with a TypeError if
  // Type([sync_iterator].return()) is not Object.
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'],
                                      kNext|kReturnUnchanged, log));
  try {
    await iter.return('not-a-JSReceiver');
    assertUnreachable('Expected `iter.return(\'not-a-JSReceiver\')` to ' +
                      'throw, but did not throw')
  } catch (e) {
    assertEquals(e.constructor, TypeError);
  }

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({ value: 'sync-value', done: false }, await iter.next('j'));
  assertEquals([
    {
      method: 'return',
      sent: 'not-a-JSReceiver',
      done: true
    },
    {
      method: 'next',
      sent: 'j',
      value: 'sync-value',
      done: false
    }
  ], log);

  // If [sync_iterator] does not have a .throw method, return a Promise rejected
  // with the sent value.
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext, log));
  try {
    await iter.throw('Boo!!');
    assertUnreachable('Expected iter.throw(\'Boo!!\') to throw, but did not ' +
                      'throw');
  } catch (e) {
    assertEquals('Boo!!', e);
  }

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({ value: 'sync-value', done: false }, await iter.next('k'));
  assertEquals([
    {
      method: 'next',
      sent: 'k',
      value: 'sync-value',
      done: false
    }
  ], log);


  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kThrow, log));
  try {
    await iter.throw('Boo!!');
    assertUnreachable('Expected iter.throw(\'Boo!!\') to throw, but did not ' +
                      'throw');
  } catch (e) {
    assertEquals('Boo!!', e);
  }

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({ value: 'sync-value', done: false }, await iter.next('l'));
  assertEquals([
    {
      method: 'throw',
      sent: 'Boo!!',
      done: false
    },
    {
      method: 'next',
      sent: 'l',
      value: 'sync-value',
      done: false
    }
  ], log);

  // If [sync_iterator].throw() returns a resolved Promise or a Completion
  // with [[Type]] "normal" or "return", return a resolved Promise
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'], kNext|kThrowNormal,
                                      log));
  assertEquals({
    value: 'Boo!!',
    done: false
  }, await iter.throw('Boo!!'));

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({ value: 'sync-value', done: false }, await iter.next('m'));
  assertEquals([
    {
      method: 'throw',
      sent: 'Boo!!',
      done: false
    },
    {
      method: 'next',
      sent: 'm',
      value: 'sync-value',
      done: false
    }
  ], log);

  // [Async-from-Sync Iterator].throw() will be rejected with a TypeError if
  // Type([sync_iterator].throw()) is not Object.
  log = [];
  iter = %CreateAsyncFromSyncIterator(sync(['sync-value'],
                                      kNext|kThrowUnchanged, log));
  try {
    await iter.throw('not-a-JSReceiver');
    assertUnreachable('Expected `iter.throw(\'not-a-JSReceiver\')` to ' +
                      'throw, but did not throw')
  } catch (e) {
    assertEquals(e.constructor, TypeError);
  }

  // [Async-from-Sync Iterator] merely delegates, and does not keep track of
  // whether [sync_iterator] is completed or not.
  assertEquals({ value: 'sync-value', done: false }, await iter.next('n'));
  assertEquals([
    {
      method: 'throw',
      sent: 'not-a-JSReceiver',
      done: false
    },
    {
      method: 'next',
      sent: 'n',
      value: 'sync-value',
      done: false
    }
  ], log);

  // Let nextValue be IteratorValue(nextResult).
  // IfAbruptRejectPromise(nextValue, promiseCapability).)
  iter = %CreateAsyncFromSyncIterator({
    next() { return { get value() { throw "BadValue!" }, done: false }; }
  });
  try {
    await iter.next();
    assertUnreachable('Expected `iter.next()` to throw, but did not throw');
  } catch (e) {
    assertEquals('BadValue!', e);
  }

  // Let nextDone be IteratorComplete(nextResult).
  // IfAbruptRejectPromise(nextDone, promiseCapability).
  iter = %CreateAsyncFromSyncIterator({
    next() { return { value: undefined, get done() { throw "BadValue!" } }; }
  });
  try {
    await iter.next();
    assertUnreachable('Expected `iter.next()` to throw, but did not throw');
  } catch (e) {
    assertEquals('BadValue!', e);
  }

  // IfAbruptRejectPromise(returnResult, promiseCapability).
  // Let returnValue be IteratorValue(returnResult).
  iter = %CreateAsyncFromSyncIterator({
    return() { return { get value() { throw "BadValue!" }, done: false }; }
  });
  try {
    await iter.return();
    assertUnreachable('Expected `iter.return()` to throw, but did not throw');
  } catch (e) {
    assertEquals('BadValue!', e);
  }

  // IfAbruptRejectPromise(returnValue, promiseCapability).
  // Let returnDone be IteratorComplete(returnResult).
  iter = %CreateAsyncFromSyncIterator({
    return() { return { value: undefined, get done() { throw "BadValue!" } }; }
  });
  try {
    await iter.return();
    assertUnreachable('Expected `iter.return()` to throw, but did not throw');
  } catch (e) {
    assertEquals('BadValue!', e);
  }

  // IfAbruptRejectPromise(throwResult, promiseCapability).
  // Let throwValue be IteratorValue(throwResult).
  iter = %CreateAsyncFromSyncIterator({
    throw() { return { get value() { throw "BadValue!" }, done: false }; }
  });
  try {
    await iter.throw();
    assertUnreachable('Expected `iter.throw()` to throw, but did not throw');
  } catch (e) {
    assertEquals('BadValue!', e);
  }

  // IfAbruptRejectPromise(throwValue, promiseCapability).
  // Let throwDone be IteratorComplete(throwResult).
  iter = %CreateAsyncFromSyncIterator({
    throw() { return { value: undefined, get done() { throw "BadValue!" } }; }
  });
  try {
    await iter.throw();
    assertUnreachable('Expected `iter.throw()` to throw, but did not throw');
  } catch (e) {
    assertEquals('BadValue!', e);
  }
})().catch(function(error) {
  testFailed = true;
  testFailure = error;
});

%PerformMicrotaskCheckpoint();
if (testFailed) {
  throw testFailure;
}

(function ExtractedAsyncFromSyncIteratorMethods() {
  // TODO(ishell, caitp): Rewrite the test without using function.caller.
  // According to ES#sec-built-in-function-objects all built-in functions
  // must be strict. And ES#sec-forbidden-extensions states that the value of
  // a function.caller must not be a strict function.
  return;
  // Async-from-Sync iterator methods can be extracted via function.caller.
  // TODO(caitp): test extracted `throw` method using yield* in async generator.
  let extractor = [0, 1, 2, 3, 4,5,6,7,8,9];
  let extractedNext;
  let extractedReturn;

  extractor[Symbol.iterator] = function() {
    let it = [][Symbol.iterator].call(extractor);
    let origNext = it.next, origThrow = it.throw, origReturn = it.return;
    function extractNext() {
      extractedNext = extractNext.caller;
      return origNext;
    }
    function extractReturn() {
      extractedReturn = extractReturn.caller;
      return origReturn;
    }
    Object.defineProperties(it, {
      "next": { get: extractNext, configurable: true },
      "return": { get: extractReturn, configurable: true }
    });
    return it;
  };

  async function f() {
    let i;
    let it = extractor[Symbol.iterator]();
    for await (let x of it) break;
    for await (let x of it) return "x";
  }

  // Cycle through `f` to extract iterator methods
  f().catch(function() { %AbortJS("No error should have occurred"); });
  %PerformMicrotaskCheckpoint();

  assertEquals(typeof extractedNext, "function");
  assertThrowsAsync(() => extractedNext.call(undefined), TypeError);
  assertThrowsAsync(() => extractedNext.call(1), TypeError);

  assertEquals(typeof extractedReturn, "function");
  assertThrowsAsync(() => extractedReturn.call(undefined), TypeError);
  assertThrowsAsync(() => extractedReturn.call(1), TypeError);
})();

(function AsyncFromSyncIteratorOrdering() {
  let i = 0;
  let log = [];
  function r(value, done) {
    let number = (++i);
    return {
      get value() {
        log.push("get iterResult #" + number + ".value");
        return {
          get then() {
            log.push("get nextValue#" + number + ".then");
            return (r) => {
              log.push("call nextValue#" + number + ".then");
              r(value);
            }
          }
        };
      },
      get done() {
        log.push("get iterResult #" + number + ".done");
        return done;
      }
    };
  }
  var results = [r("value1", false), r("value2", false), r("value3", true),
                 r("value4", false)];

  var iter = {
    get [Symbol.asyncIterator]() {
      log.push("get syncIterable[@@asyncIterator]");
      return null;
    },

    get [Symbol.iterator]() {
      log.push("get syncIterable[@@iterator]");
      return (...args) => {
        log.push("call syncIterable[@@iterator](" + args.join(", ") + ")");
        return this;
      }
    },
    next_: 0,
    get next() {
      log.push("get syncIterable.next");
      return (...args) => {
        let i = this.next_++;
        log.push("call syncIterable.next(" + args.join(", ") + ")");
        return results[i];
      }
    }
  };

  async function iterate(iterable) {
    log.push("before");
    for await (let x of iterable) {
      log.push("got value " + x);
    }
    log.push("after");

    return log;
  }

  iterate(iter).then(log => {
    assertEquals([
      "before",
      "get syncIterable[@@asyncIterator]",
      "get syncIterable[@@iterator]",
      "call syncIterable[@@iterator]()",
      "get syncIterable.next",
      "call syncIterable.next()",
      "get iterResult #1.done",
      "get iterResult #1.value",
      "get nextValue#1.then",
      "call nextValue#1.then",
      "got value value1",
      "call syncIterable.next()",
      "get iterResult #2.done",
      "get iterResult #2.value",
      "get nextValue#2.then",
      "call nextValue#2.then",
      "got value value2",
      "call syncIterable.next()",
      "get iterResult #3.done",
      "get iterResult #3.value",
      "get nextValue#3.then",
      "call nextValue#3.then",
      "after"
    ], log)
  }).catch(x => %AbortJS(String(x)));
})();
