'use strict';

var GetIntrinsic = require('./GetIntrinsic');

var ES2016 = require('./es2016'); var assign = require('./helpers/assign'); var forEach = require('./helpers/forEach'); var callBind = require('./helpers/callBind');

var $TypeError = GetIntrinsic('%TypeError%'); var callBound = require('./helpers/callBound'); var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable'); var $pushApply = callBind.apply(GetIntrinsic('%Array.prototype.push%')); var $arrayPush = callBound('Array.prototype.push');

var ES2017 = assign(assign({}, ES2016), {

ToIndex: function ToIndex(value) {
        if (typeof value === 'undefined') {
                return 0;
        }
        var integerIndex = this.ToInteger(value);
        if (integerIndex < 0) {
                throw new RangeError('index must be >= 0');
        }
        var index = this.ToLength(integerIndex);
        if (!this.SameValueZero(integerIndex, index)) {
                throw new RangeError('index must be >= 0 and < 2 ** 53 - 1');
        }
        return index;
},

// https://www.ecma-international.org/ecma-262/8.0/#sec-enumerableownproperties
EnumerableOwnProperties: function EnumerableOwnProperties(O, kind) {
        var keys = ES2016.EnumerableOwnNames(O);
        if (kind === 'key') {
                return keys;
        }
        if (kind === 'value' || kind === 'key+value') {
                var results = [];
                forEach(keys, function (key) {
                        if ($isEnumerable(O, key)) {
                                $pushApply(results, [
                                        kind === 'value' ? O[key] : [key, O[key]]
                                ]);
                        }
                });
                return results;
        }
        throw new $TypeError('Assertion failed: "kind" is not "key", "value", or "key+value": ' + kind);
},

// https://www.ecma-international.org/ecma-262/8.0/#sec-iterabletolist
IterableToList: function IterableToList(items, method) {
        var iterator = this.GetIterator(items, method);
        var values = [];
        var next = true;
        while (next) {
                next = this.IteratorStep(iterator);
                if (next) {
                        var nextValue = this.IteratorValue(next);
                        $arrayPush(values, nextValue);
                }
        }
        return values;
}

});

delete ES2017.EnumerableOwnNames; // replaced with EnumerableOwnProperties delete ES2017.IterableToArrayLike; // replaced with IterableToList

module.exports = ES2017;