// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart._interceptors;

/**
 * The interceptor class for [List]. The compiler recognizes this
 * class as an interceptor, and changes references to [:this:] to
 * actually use the receiver of the method, which is generated as an extra
 * argument added to each member.
 */
@JsPeerInterface(name: 'Array')
class JSArray<E> implements List<E>, JSIndexable<E> {
  const JSArray();

  /**
   * Constructor for adding type parameters to an existing JavaScript
   * Array. Used for creating literal lists.
   */
  factory JSArray.of(list) {
    // TODO(sra): Move this to core.List for better readability.
    //
    // TODO(jmesserly): this uses special compiler magic to close over the
    // parameterized ES6 'JSArray' class.
    JS('', '#.__proto__ = JSArray.prototype', list);
    return JS('-dynamic', '#', list);
  }

  // TODO(jmesserly): consider a fixed array subclass instead.
  factory JSArray.fixed(list) {
    JS('', '#.__proto__ = JSArray.prototype', list);
    JS('', r'#.fixed$length = Array', list);
    return JS('-dynamic', '#', list);
  }

  factory JSArray.unmodifiable(list) {
    JS('', '#.__proto__ = JSArray.prototype', list);
    JS('', r'#.fixed$length = Array', list);
    JS('', r'#.immutable$list = Array', list);
    return JS('-dynamic', '#', list);
  }

  static void markFixedList(list) {
    // Functions are stored in the hidden class and not as properties in
    // the object. We never actually look at the value, but only want
    // to know if the property exists.
    JS('', r'#.fixed$length = Array', list);
  }

  static void markUnmodifiableList(list) {
    // Functions are stored in the hidden class and not as properties in
    // the object. We never actually look at the value, but only want
    // to know if the property exists.
    JS('', r'#.fixed$length = Array', list);
    JS('', r'#.immutable$list = Array', list);
  }

  checkMutable(reason) {
    if (JS<bool>('!', r'#.immutable$list', this)) {
      throw UnsupportedError(reason);
    }
  }

  checkGrowable(reason) {
    if (JS<bool>('!', r'#.fixed$length', this)) {
      throw UnsupportedError(reason);
    }
  }

  List<R> cast<R>() => List.castFrom<E, R>(this);
  void add(E value) {
    checkGrowable('add');
    JS('void', r'#.push(#)', this, value);
  }

  E removeAt(@nullCheck int index) {
    checkGrowable('removeAt');
    if (index < 0 || index >= length) {
      throw RangeError.value(index);
    }
    return JS('-dynamic', r'#.splice(#, 1)[0]', this, index);
  }

  void insert(@nullCheck int index, E value) {
    checkGrowable('insert');
    if (index < 0 || index > length) {
      throw RangeError.value(index);
    }
    JS('void', r'#.splice(#, 0, #)', this, index, value);
  }

  void insertAll(@nullCheck int index, Iterable<E> iterable) {
    checkGrowable('insertAll');
    RangeError.checkValueInInterval(index, 0, this.length, "index");
    if (iterable is! EfficientLengthIterable) {
      iterable = iterable.toList();
    }
    @nullCheck
    int insertionLength = iterable.length;
    this.length += insertionLength;
    int end = index + insertionLength;
    this.setRange(end, this.length, this, index);
    this.setRange(index, end, iterable);
  }

  void setAll(@nullCheck int index, Iterable<E> iterable) {
    checkMutable('setAll');
    RangeError.checkValueInInterval(index, 0, this.length, "index");
    for (var element in iterable) {
      this[index++] = element;
    }
  }

  E removeLast() {
    checkGrowable('removeLast');
    if (length == 0) throw diagnoseIndexError(this, -1);
    return JS('var', r'#.pop()', this);
  }

  bool remove(Object? element) {
    checkGrowable('remove');
    var length = this.length;
    for (int i = 0; i < length; i++) {
      if (this[i] == element) {
        JS('var', r'#.splice(#, 1)', this, i);
        return true;
      }
    }
    return false;
  }

  /**
   * Removes elements matching [test] from [this] List.
   */
  void removeWhere(bool Function(E) test) {
    checkGrowable('removeWhere');
    _removeWhere(test, true);
  }

  void retainWhere(bool Function(E) test) {
    checkGrowable('retainWhere');
    _removeWhere(test, false);
  }

  void _removeWhere(bool Function(E) test, bool removeMatching) {
    // Performed in two steps, to avoid exposing an inconsistent state
    // to the [test] function. First the elements to retain are found, and then
    // the original list is updated to contain those elements.

    // TODO(sra): Replace this algorithm with one that retains a list of ranges
    // to be removed.  Most real uses remove 0, 1 or a few clustered elements.

    List retained = [];
    int end = this.length;
    for (int i = 0; i < end; i++) {
      var element = JS<E>('-dynamic', '#[#]', this, i);
      // !test() ensures bool conversion in checked mode.
      if (!test(element) == removeMatching) {
        retained.add(element);
      }
      if (this.length != end) throw ConcurrentModificationError(this);
    }
    if (retained.length == end) return;
    this.length = retained.length;
    @nullCheck
    var length = retained.length;
    for (int i = 0; i < length; i++) {
      JS('', '#[#] = #[#]', this, i, retained, i);
    }
  }

  Iterable<E> where(bool Function(E) f) {
    return WhereIterable<E>(this, f);
  }

  Iterable<T> expand<T>(Iterable<T> Function(E) f) {
    return ExpandIterable<E, T>(this, f);
  }

  void addAll(Iterable<E> collection) {
    int i = this.length;
    checkGrowable('addAll');
    for (E e in collection) {
      assert(i == this.length || (throw ConcurrentModificationError(this)));
      i++;
      JS('void', r'#.push(#)', this, e);
    }
  }

  void clear() {
    length = 0;
  }

  void forEach(void Function(E) f) {
    int end = this.length;
    for (int i = 0; i < end; i++) {
      var element = JS<E>('', '#[#]', this, i);
      f(element);
      if (this.length != end) throw ConcurrentModificationError(this);
    }
  }

  Iterable<T> map<T>(T Function(E) f) {
    return MappedListIterable<E, T>(this, f);
  }

  String join([String separator = ""]) {
    var length = this.length;
    var list = List<String>.filled(length, "");
    for (int i = 0; i < length; i++) {
      list[i] = "${this[i]}";
    }
    return JS<String>('!', "#.join(#)", list, separator);
  }

  Iterable<E> take(int n) {
    return SubListIterable<E>(this, 0, n);
  }

  Iterable<E> takeWhile(bool test(E value)) {
    return TakeWhileIterable<E>(this, test);
  }

  Iterable<E> skip(int n) {
    return SubListIterable<E>(this, n, null);
  }

  Iterable<E> skipWhile(bool Function(E) test) {
    return SkipWhileIterable<E>(this, test);
  }

  E reduce(E combine(E previousValue, E element)) {
    int length = this.length;
    if (length == 0) throw IterableElementError.noElement();
    E value = this[0];
    for (int i = 1; i < length; i++) {
      var element = JS<E>('', '#[#]', this, i);
      value = combine(value, element);
      if (length != this.length) throw ConcurrentModificationError(this);
    }
    return value;
  }

  T fold<T>(T initialValue, T Function(T previousValue, E element) combine) {
    var value = initialValue;
    int length = this.length;
    for (int i = 0; i < length; i++) {
      var element = JS<E>('', '#[#]', this, i);
      value = combine(value, element);
      if (this.length != length) throw ConcurrentModificationError(this);
    }
    return value;
  }

  E firstWhere(bool Function(E) test, {E Function()? orElse}) {
    int end = this.length;
    for (int i = 0; i < end; ++i) {
      var element = JS<E>('', '#[#]', this, i);
      if (test(element)) return element;
      if (this.length != end) throw ConcurrentModificationError(this);
    }
    if (orElse != null) return orElse();
    throw IterableElementError.noElement();
  }

  E lastWhere(bool Function(E) test, {E Function()? orElse}) {
    int length = this.length;
    for (int i = length - 1; i >= 0; i--) {
      var element = JS<E>('', '#[#]', this, i);
      if (test(element)) return element;
      if (length != this.length) {
        throw ConcurrentModificationError(this);
      }
    }
    if (orElse != null) return orElse();
    throw IterableElementError.noElement();
  }

  E singleWhere(bool Function(E) test, {E Function()? orElse}) {
    int length = this.length;
    E? match = null;
    bool matchFound = false;
    for (int i = 0; i < length; i++) {
      var element = JS<E>('-dynamic', '#[#]', this, i);
      if (test(element)) {
        if (matchFound) {
          throw IterableElementError.tooMany();
        }
        matchFound = true;
        match = element;
      }
      if (length != this.length) {
        throw ConcurrentModificationError(this);
      }
    }
    if (matchFound) return match!;
    if (orElse != null) return orElse();
    throw IterableElementError.noElement();
  }

  E elementAt(int index) {
    return this[index];
  }

  List<E> sublist(@nullCheck int start, [int? end]) {
    if (start < 0 || start > length) {
      throw RangeError.range(start, 0, length, "start");
    }
    if (end == null) {
      end = length;
    } else {
      @notNull
      var _end = end;
      if (_end < start || _end > length) {
        throw RangeError.range(end, start, length, "end");
      }
    }
    if (start == end) return <E>[];
    return JSArray<E>.of(JS('', r'#.slice(#, #)', this, start, end));
  }

  Iterable<E> getRange(int start, int end) {
    RangeError.checkValidRange(start, end, this.length);
    return SubListIterable<E>(this, start, end);
  }

  E get first {
    if (length > 0) return this[0];
    throw IterableElementError.noElement();
  }

  E get last {
    if (length > 0) return this[length - 1];
    throw IterableElementError.noElement();
  }

  E get single {
    if (length == 1) return this[0];
    if (length == 0) throw IterableElementError.noElement();
    throw IterableElementError.tooMany();
  }

  void removeRange(@nullCheck int start, @nullCheck int end) {
    checkGrowable('removeRange');
    RangeError.checkValidRange(start, end, this.length);
    int deleteCount = end - start;
    JS('', '#.splice(#, #)', this, start, deleteCount);
  }

  void setRange(@nullCheck int start, @nullCheck int end, Iterable<E> iterable,
      [@nullCheck int skipCount = 0]) {
    checkMutable('set range');

    RangeError.checkValidRange(start, end, this.length);
    int length = end - start;
    if (length == 0) return;
    RangeError.checkNotNegative(skipCount, "skipCount");

    var otherList = <E>[];
    int otherStart = 0;
    // TODO(floitsch): Make this accept more.
    if (iterable is List<E>) {
      otherList = iterable;
      otherStart = skipCount;
    } else {
      otherList = iterable.skip(skipCount).toList(growable: false);
      otherStart = 0;
    }
    if (otherStart + length > otherList.length) {
      throw IterableElementError.tooFew();
    }
    if (otherStart < start) {
      // Copy backwards to ensure correct copy if [from] is this.
      // TODO(sra): If [from] is the same Array as [this], we can copy without
      // type annotation checks on the stores.
      for (int i = length - 1; i >= 0; i--) {
        // Use JS to avoid bounds check (the bounds check elimination
        // optimzation is too weak). The 'E' type annotation is a store type
        // check - we can't rely on iterable, it could be List<dynamic>.
        E element = otherList[otherStart + i];
        JS('', '#[#] = #', this, start + i, element);
      }
    } else {
      for (int i = 0; i < length; i++) {
        E element = otherList[otherStart + i];
        JS('', '#[#] = #', this, start + i, element);
      }
    }
  }

  void fillRange(@nullCheck int start, @nullCheck int end, [E? fillValue]) {
    checkMutable('fill range');
    RangeError.checkValidRange(start, end, this.length);
    E checkedFillValue = fillValue as E;
    for (int i = start; i < end; i++) {
      JS('', '#[#] = #', this, i, checkedFillValue);
    }
  }

  void replaceRange(
      @nullCheck int start, @nullCheck int end, Iterable<E> replacement) {
    checkGrowable('replace range');
    RangeError.checkValidRange(start, end, this.length);
    if (replacement is! EfficientLengthIterable) {
      replacement = replacement.toList();
    }
    int removeLength = end - start;
    @nullCheck
    int insertLength = replacement.length;
    if (removeLength >= insertLength) {
      int delta = removeLength - insertLength;
      int insertEnd = start + insertLength;
      int newLength = this.length - delta;
      this.setRange(start, insertEnd, replacement);
      if (delta != 0) {
        this.setRange(insertEnd, newLength, this, end);
        this.length = newLength;
      }
    } else {
      int delta = insertLength - removeLength;
      int newLength = this.length + delta;
      int insertEnd = start + insertLength; // aka. end + delta.
      this.length = newLength;
      this.setRange(insertEnd, newLength, this, end);
      this.setRange(start, insertEnd, replacement);
    }
  }

  bool any(bool Function(E) test) {
    int end = this.length;
    for (int i = 0; i < end; i++) {
      var element = JS<E>('', '#[#]', this, i);
      if (test(element)) return true;
      if (this.length != end) throw ConcurrentModificationError(this);
    }
    return false;
  }

  bool every(bool Function(E) test) {
    int end = this.length;
    for (int i = 0; i < end; i++) {
      var element = JS<E>('-dynamic', '#[#]', this, i);
      if (!test(element)) return false;
      if (this.length != end) throw ConcurrentModificationError(this);
    }
    return true;
  }

  Iterable<E> get reversed => ReversedListIterable<E>(this);

  void sort([int Function(E, E)? compare]) {
    checkMutable('sort');
    if (compare == null) {
      Sort.sort(
          this, (a, b) => Comparable.compare(a as Comparable, b as Comparable));
    } else {
      Sort.sort(this, compare);
    }
  }

  void shuffle([Random? random]) {
    checkMutable('shuffle');
    if (random == null) random = Random();
    int length = this.length;
    while (length > 1) {
      int pos = random.nextInt(length);
      length -= 1;
      var tmp = this[length];
      this[length] = this[pos];
      this[pos] = tmp;
    }
  }

  int indexOf(Object? element, [@nullCheck int start = 0]) {
    int length = this.length;
    if (start >= length) {
      return -1;
    }
    if (start < 0) {
      start = 0;
    }
    for (int i = start; i < length; i++) {
      if (this[i] == element) {
        return i;
      }
    }
    return -1;
  }

  int lastIndexOf(Object? element, [int? _startIndex]) {
    @notNull
    int startIndex = _startIndex ?? this.length - 1;
    if (startIndex >= this.length) {
      startIndex = this.length - 1;
    } else if (startIndex < 0) {
      return -1;
    }
    for (int i = startIndex; i >= 0; i--) {
      if (this[i] == element) {
        return i;
      }
    }
    return -1;
  }

  bool contains(Object? other) {
    var length = this.length;
    for (int i = 0; i < length; i++) {
      E element = JS('Null', '#[#]', this, i);
      if (element == other) return true;
    }
    return false;
  }

  @notNull
  bool get isEmpty => length == 0;

  @notNull
  bool get isNotEmpty => !isEmpty;

  String toString() => ListBase.listToString(this);

  List<E> toList({@nullCheck bool growable = true}) {
    var list = JS('', '#.slice()', this);
    if (!growable) markFixedList(list);
    return JSArray<E>.of(list);
  }

  Set<E> toSet() => Set<E>.from(this);

  Iterator<E> get iterator => ArrayIterator<E>(this);

  int get hashCode => identityHashCode(this);

  @notNull
  bool operator ==(other) => identical(this, other);

  @notNull
  int get length => JS<int>('!', r'#.length', this);

  void set length(@nullCheck int newLength) {
    checkGrowable('set length');
    // TODO(sra): Remove this test and let JavaScript throw an error.
    if (newLength < 0) {
      throw RangeError.range(newLength, 0, null, 'newLength');
    }
    // JavaScript with throw a RangeError for numbers that are too big. The
    // message does not contain the value.
    JS('void', r'#.length = #', this, newLength);
  }

  E operator [](int index) {
    // Suppress redundant null checks via JS.
    if (JS<int>('!', '#', index) >= JS<int>('!', '#.length', this) ||
        JS<int>('!', '#', index) < 0) {
      throw diagnoseIndexError(this, index);
    }
    return JS<E>('', '#[#]', this, index);
  }

  void operator []=(int index, E value) {
    checkMutable('indexed set');
    if (JS<int>('!', '#', index) >= JS<int>('!', '#.length', this) ||
        JS<int>('!', '#', index) < 0) {
      throw diagnoseIndexError(this, index);
    }
    JS('void', r'#[#] = #', this, index, value);
  }

  Map<int, E> asMap() {
    return ListMapView<E>(this);
  }

  Type get runtimeType =>
      dart.wrapType(JS('', '#(#)', dart.getGenericClass(List), E));

  Iterable<E> followedBy(Iterable<E> other) =>
      FollowedByIterable<E>.firstEfficient(this, other);

  Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);

  List<E> operator +(List<E> other) {
    int totalLength = this.length + other.length;
    return <E>[]
      ..length = totalLength
      ..setRange(0, this.length, this)
      ..setRange(this.length, totalLength, other);
  }

  int indexWhere(bool Function(E) test, [int start = 0]) {
    if (start >= this.length) return -1;
    if (start < 0) start = 0;
    for (int i = start; i < this.length; i++) {
      if (test(this[i])) return i;
    }
    return -1;
  }

  int lastIndexWhere(bool Function(E) test, [int? start]) {
    if (start == null) start = this.length - 1;
    if (start < 0) return -1;
    for (int i = start; i >= 0; i--) {
      if (test(this[i])) return i;
    }
    return -1;
  }

  void set first(E element) {
    if (this.isEmpty) throw RangeError.index(0, this);
    this[0] = element;
  }

  void set last(E element) {
    if (this.isEmpty) throw RangeError.index(0, this);
    this[this.length - 1] = element;
  }
}

/**
 * Dummy subclasses that allow the backend to track more precise
 * information about arrays through their type. The CPA type inference
 * relies on the fact that these classes do not override [] nor []=.
 *
 * These classes are really a fiction, and can have no methods, since
 * getInterceptor always returns JSArray.  We should consider pushing the
 * 'isGrowable' and 'isMutable' checks into the getInterceptor implementation so
 * these classes can have specialized implementations. Doing so will challenge
 * many assumptions in the JS backend.
 */
class JSMutableArray<E> extends JSArray<E> {}

class JSFixedArray<E> extends JSMutableArray<E> {}

class JSExtendableArray<E> extends JSMutableArray<E> {}

class JSUnmodifiableArray<E> extends JSArray<E> {} // Already is JSIndexable.

/// An [Iterator] that iterates a JSArray.
///
class ArrayIterator<E> implements Iterator<E> {
  final JSArray<E> _iterable;
  @notNull
  final int _length;
  @notNull
  int _index;
  E? _current;

  ArrayIterator(JSArray<E> iterable)
      : _iterable = iterable,
        _length = iterable.length,
        _index = 0;

  E get current => _current as E;

  bool moveNext() {
    @notNull
    int length = _iterable.length;

    // We have to do the length check even on fixed length Arrays.  If we can
    // inline moveNext() we might be able to GVN the length and eliminate this
    // check on known fixed length JSArray.
    if (_length != length) {
      throw throwConcurrentModificationError(_iterable);
    }

    if (_index >= length) {
      _current = null;
      return false;
    }
    _current = _iterable[_index];
    _index++;
    return true;
  }
}
