// Copyright (c) 2011, 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.

// @dart = 2.9

part of utilslib;

typedef num NumericValueSelector<T>(T value);

/**
 * General purpose collection utilities.
 * TODO(jmesserly): make these top level functions?
 */
class CollectionUtils {
  static void insertAt(List arr, int pos, value) {
    assert(pos >= 0);
    assert(pos <= arr.length);

    if (pos == arr.length) {
      arr.add(value);
    } else {
      // TODO(sigmund): replace this push with a call that ensures capacity
      // (currently not supported in the JS implementation of list). E.g.
      // [: arr.length = arr.length + 1; :]
      arr.add(null);

      // shift elements from [pos] (note: arr already has null @ length - 1)
      for (int i = arr.length - 2; i >= pos; i--) {
        arr[i + 1] = arr[i];
      }
      arr[pos] = value;

      // TODO(jmesserly): we won't need to do this once List
      // implements insertAt
      if (arr is ObservableList) {
        // TODO(jmesserly): shouldn't need to cast after testing instanceof
        ObservableList obs = arr;
        obs.recordListInsert(pos, value);
      }
    }
  }

  /**
   * Finds the item in [source] that matches [test].  Returns null if
   * no item matches.  The typing should be:
   * T find(Iterable<T> source, bool test(T item)), but we don't have generic
   * functions.
   */
  static find(Iterable source, bool test(item)) {
    for (final item in source) {
      if (test(item)) return item;
    }

    return null;
  }

  /** Compute the minimum of an iterable. Returns null if empty. */
  static num min(Iterable source) {
    final iter = source.iterator;
    if (!iter.moveNext()) {
      return null;
    }
    num best = iter.current;
    while (iter.moveNext()) {
      best = Math.min(best, iter.current);
    }
    return best;
  }

  /** Compute the maximum of an iterable. Returns null if empty. */
  static num max(Iterable source) {
    final iter = source.iterator;
    if (!iter.moveNext()) {
      return null;
    }
    num best = iter.current;
    while (iter.moveNext()) {
      best = Math.max(best, iter.current);
    }
    return best;
  }

  /** Orders an iterable by its values, or by a key selector. */
  static List orderBy(Iterable source, [NumericValueSelector selector = null]) {
    final result = new List.from(source);
    sortBy(result, selector);
    return result;
  }

  /** Sorts a list by its values, or by a key selector. */
  // TODO(jmesserly): we probably don't want to call the key selector more than
  // once for a given element. This would improve performance and the API
  // contract could be stronger.
  static void sortBy(List list, [NumericValueSelector selector = null]) {
    if (selector != null) {
      list.sort((x, y) => selector(x) - selector(y));
    } else {
      list.sort((x, y) => x - y);
    }
  }

  /** Compute the sum of an iterable. An empty iterable is an error. */
  static num sum(Iterable source, [NumericValueSelector selector = null]) {
    final iter = source.iterator;
    bool wasEmpty = true;
    num total = 0;
    if (selector != null) {
      for (var element in source) {
        wasEmpty = false;
        total += selector(element);
      }
    } else {
      for (num element in source) {
        wasEmpty = false;
        total += element;
      }
    }
    if (wasEmpty) throw new StateError("No elements");
    return total;
  }

  // TODO(jmesserly): something like should exist on Map, either a method or a
  // constructor, see bug #5340679
  static void copyMap(Map dest, Map source) {
    for (final k in source.keys) {
      dest[k] = source[k];
    }
  }
}
