var global = require('../internals/global');
var shared = require('../internals/shared-store');
var getPrototypeOf = require('../internals/object-get-prototype-of');
var has = require('../internals/has');
var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
var wellKnownSymbol = require('../internals/well-known-symbol');
var IS_PURE = require('../internals/is-pure');

var USE_FUNCTION_CONSTRUCTOR = 'USE_FUNCTION_CONSTRUCTOR';
var ASYNC_ITERATOR = wellKnownSymbol('asyncIterator');
var AsyncIterator = global.AsyncIterator;
var PassedAsyncIteratorPrototype = shared.AsyncIteratorPrototype;
var AsyncIteratorPrototype, prototype;

if (!IS_PURE) {
  if (PassedAsyncIteratorPrototype) {
    AsyncIteratorPrototype = PassedAsyncIteratorPrototype;
  } else if (typeof AsyncIterator == 'function') {
    AsyncIteratorPrototype = AsyncIterator.prototype;
  } else if (shared[USE_FUNCTION_CONSTRUCTOR] || global[USE_FUNCTION_CONSTRUCTOR]) {
    try {
      // eslint-disable-next-line no-new-func -- we have no alternatives without usage of modern syntax
      prototype = getPrototypeOf(getPrototypeOf(getPrototypeOf(Function('return async function*(){}()')())));
      if (getPrototypeOf(prototype) === Object.prototype) AsyncIteratorPrototype = prototype;
    } catch (error) { /* empty */ }
  }
}

if (!AsyncIteratorPrototype) AsyncIteratorPrototype = {};

if (!has(AsyncIteratorPrototype, ASYNC_ITERATOR)) {
  createNonEnumerableProperty(AsyncIteratorPrototype, ASYNC_ITERATOR, function () {
    return this;
  });
}

module.exports = AsyncIteratorPrototype;
