// 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);

  %RunMicrotasks();

  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;
});

%RunMicrotasks();
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;
});

%RunMicrotasks();
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"); });
  %RunMicrotasks();

  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");
      let i = this.next_++;
      return (...args) => {
        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",
      "get syncIterable.next",
      "call syncIterable.next()",
      "get iterResult #2.done",
      "get iterResult #2.value",
      "get nextValue#2.then",
      "call nextValue#2.then",
      "got value value2",
      "get syncIterable.next",
      "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)));
})();
