// Copyright (c) 2017, 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._js_helper;

class CustomKeyHashMap<K, V> extends CustomHashMap<K, V> {
  final _Predicate<Object> _validKey;
  CustomKeyHashMap(_Equality<K> equals, _Hasher<K> hashCode, this._validKey)
      : super(equals, hashCode);

  @override
  @notNull
  bool containsKey(Object key) {
    if (!_validKey(key)) return false;
    return super.containsKey(key);
  }

  @override
  V operator [](Object key) {
    if (!_validKey(key)) return null;
    return super[key];
  }

  @override
  V remove(Object key) {
    if (!_validKey(key)) return null;
    return super.remove(key);
  }
}

class CustomHashMap<K, V> extends InternalMap<K, V> {
  /// The backing store for this map.
  @notNull
  final _map = JS('', 'new Map()');

  /// Our map used to map keys onto the canonical key that is stored in [_map].
  @notNull
  final _keyMap = JS('', 'new Map()');

  // We track the number of modifications done to the key set of the
  // hash map to be able to throw when the map is modified while being
  // iterated over.
  //
  // Value cycles after 2^30 modifications so that modification counts are
  // always unboxed (Smi) values. Modification detection will be missed if you
  // make exactly some multiple of 2^30 modifications between advances of an
  // iterator.
  @notNull
  int _modifications = 0;

  final _Equality<K> _equals;
  final _Hasher<K> _hashCode;

  CustomHashMap(this._equals, this._hashCode);

  @notNull
  int get length => JS('int', '#.size', _map);

  @notNull
  bool get isEmpty => JS('bool', '#.size == 0', _map);

  @notNull
  bool get isNotEmpty => JS('bool', '#.size != 0', _map);

  Iterable<K> get keys => _JSMapIterable<K>(this, true);
  Iterable<V> get values => _JSMapIterable<V>(this, false);

  @notNull
  bool containsKey(Object key) {
    if (key is K) {
      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
      if (buckets != null) {
        var equals = _equals;
        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
          K k = JS('', '#[#]', buckets, i);
          if (equals(k, key)) return true;
        }
      }
    }
    return false;
  }

  bool containsValue(Object value) {
    for (var v in JS('', '#.values()', _map)) {
      if (value == v) return true;
    }
    return false;
  }

  void addAll(Map<K, V> other) {
    other.forEach((K key, V value) {
      this[key] = value;
    });
  }

  V operator [](Object key) {
    if (key is K) {
      var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
      if (buckets != null) {
        var equals = _equals;
        for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
          K k = JS('', '#[#]', buckets, i);
          if (equals(k, key)) {
            V value = JS('', '#.get(#)', _map, k);
            return value == null ? null : value; // coerce undefined to null.
          }
        }
      }
    }
    return null;
  }

  void operator []=(K key, V value) {
    var keyMap = _keyMap;
    int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
    var buckets = JS('', '#.get(#)', keyMap, hash);
    if (buckets == null) {
      JS('', '#.set(#, [#])', keyMap, hash, key);
    } else {
      var equals = _equals;
      for (int i = 0, n = JS('int', '#.length', buckets);;) {
        K k = JS('', '#[#]', buckets, i);
        if (equals(k, key)) {
          key = k;
          break;
        }
        if (++i >= n) {
          JS('', '#.push(#)', buckets, key);
          break;
        }
      }
    }
    JS('', '#.set(#, #)', _map, key, value);
    _modifications = (_modifications + 1) & 0x3ffffff;
  }

  V putIfAbsent(K key, V ifAbsent()) {
    var keyMap = _keyMap;
    int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
    var buckets = JS('', '#.get(#)', keyMap, hash);
    if (buckets == null) {
      JS('', '#.set(#, [#])', keyMap, hash, key);
    } else {
      var equals = _equals;
      for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
        K k = JS('', '#[#]', buckets, i);
        if (equals(k, key)) return JS('', '#.get(#)', _map, k);
      }
      JS('', '#.push(#)', buckets, key);
    }
    V value = ifAbsent();
    if (value == null) value = null; // coerce undefined to null.
    JS('', '#.set(#, #)', _map, key, value);
    _modifications = (_modifications + 1) & 0x3ffffff;
    return value;
  }

  V remove(Object key) {
    if (key is K) {
      int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
      var keyMap = _keyMap;
      var buckets = JS('', '#.get(#)', keyMap, hash);
      if (buckets == null) return null; // not found
      var equals = _equals;
      for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
        K k = JS('', '#[#]', buckets, i);
        if (equals(k, key)) {
          if (n == 1) {
            JS('', '#.delete(#)', keyMap, hash);
          } else {
            JS('', '#.splice(#, 1)', buckets, i);
          }
          var map = _map;
          V value = JS('', '#.get(#)', map, k);
          JS('', '#.delete(#)', map, k);
          _modifications = (_modifications + 1) & 0x3ffffff;
          return value == null ? null : value; // coerce undefined to null.
        }
      }
    }
    return null;
  }

  void clear() {
    var map = _map;
    if (JS<int>('!', '#.size', map) > 0) {
      JS('', '#.clear()', map);
      JS('', '#.clear()', _keyMap);
      _modifications = (_modifications + 1) & 0x3ffffff;
    }
  }
}

typedef bool _Equality<K>(K a, K b);
typedef int _Hasher<K>(K object);
typedef bool _Predicate<T>(T value);
