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

// Efficient JavaScript based implementation of a linked hash map used as a
// backing map for constant maps and the [LinkedHashMap] patch

part of _js_helper;

const _USE_ES6_MAPS = const bool.fromEnvironment("dart2js.use.es6.maps");

class JsLinkedHashMap<K, V> extends MapBase<K, V>
    implements LinkedHashMap<K, V>, InternalMap {
  int _length = 0;

  // The hash map contents are divided into three parts: one part for
  // string keys, one for numeric keys, and one for the rest. String
  // and numeric keys map directly to their linked cells, but the rest
  // of the entries are stored in bucket lists of the form:
  //
  //    [cell-0, cell-1, ...]
  //
  // where all keys in the same bucket share the same hash code.
  var _strings;
  var _nums;
  var _rest;

  // The keys and values are stored in cells that are linked together
  // to form a double linked list.
  LinkedHashMapCell _first;
  LinkedHashMapCell _last;

  // 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.
  int _modifications = 0;

  static bool get _supportsEs6Maps {
    return JS('returns:bool;depends:none;effects:none;throws:never;gvn:true',
        'typeof Map != "undefined"');
  }

  JsLinkedHashMap();

  /// If ES6 Maps are available returns a linked hash-map backed by an ES6 Map.
  @pragma('dart2js:tryInline')
  factory JsLinkedHashMap.es6() {
    return (_USE_ES6_MAPS && JsLinkedHashMap._supportsEs6Maps)
        ? new Es6LinkedHashMap<K, V>()
        : new JsLinkedHashMap<K, V>();
  }

  int get length => _length;
  bool get isEmpty => _length == 0;
  bool get isNotEmpty => !isEmpty;

  Iterable<K> get keys {
    return new LinkedHashMapKeyIterable<K>(this);
  }

  Iterable<V> get values {
    return new MappedIterable<K, V>(keys, (each) => this[each]);
  }

  bool containsKey(Object key) {
    if (_isStringKey(key)) {
      var strings = _strings;
      if (strings == null) return false;
      return _containsTableEntry(strings, key);
    } else if (_isNumericKey(key)) {
      var nums = _nums;
      if (nums == null) return false;
      return _containsTableEntry(nums, key);
    } else {
      return internalContainsKey(key);
    }
  }

  bool internalContainsKey(Object key) {
    var rest = _rest;
    if (rest == null) return false;
    var bucket = _getBucket(rest, key);
    return internalFindBucketIndex(bucket, key) >= 0;
  }

  bool containsValue(Object value) {
    return keys.any((each) => this[each] == value);
  }

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

  V operator [](Object key) {
    if (_isStringKey(key)) {
      var strings = _strings;
      if (strings == null) return null;
      LinkedHashMapCell cell = _getTableCell(strings, key);
      return JS('', '#', cell == null ? null : cell.hashMapCellValue);
    } else if (_isNumericKey(key)) {
      var nums = _nums;
      if (nums == null) return null;
      LinkedHashMapCell cell = _getTableCell(nums, key);
      return JS('', '#', cell == null ? null : cell.hashMapCellValue);
    } else {
      return internalGet(key);
    }
  }

  V internalGet(Object key) {
    var rest = _rest;
    if (rest == null) return null;
    var bucket = _getBucket(rest, key);
    int index = internalFindBucketIndex(bucket, key);
    if (index < 0) return null;
    LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
    return JS('', '#', cell.hashMapCellValue);
  }

  void operator []=(K key, V value) {
    if (_isStringKey(key)) {
      var strings = _strings;
      if (strings == null) _strings = strings = _newHashTable();
      _addHashTableEntry(strings, key, value);
    } else if (_isNumericKey(key)) {
      var nums = _nums;
      if (nums == null) _nums = nums = _newHashTable();
      _addHashTableEntry(nums, key, value);
    } else {
      internalSet(key, value);
    }
  }

  void internalSet(K key, V value) {
    var rest = _rest;
    if (rest == null) _rest = rest = _newHashTable();
    var hash = internalComputeHashCode(key);
    var bucket = _getTableBucket(rest, hash);
    if (bucket == null) {
      LinkedHashMapCell cell = _newLinkedCell(key, value);
      _setTableEntry(rest, hash, JS('var', '[#]', cell));
    } else {
      int index = internalFindBucketIndex(bucket, key);
      if (index >= 0) {
        LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
        cell.hashMapCellValue = value;
      } else {
        LinkedHashMapCell cell = _newLinkedCell(key, value);
        JS('void', '#.push(#)', bucket, cell);
      }
    }
  }

  V putIfAbsent(K key, V ifAbsent()) {
    if (containsKey(key)) return this[key];
    V value = ifAbsent();
    this[key] = value;
    return value;
  }

  V remove(Object key) {
    if (_isStringKey(key)) {
      return _removeHashTableEntry(_strings, key);
    } else if (_isNumericKey(key)) {
      return _removeHashTableEntry(_nums, key);
    } else {
      return internalRemove(key);
    }
  }

  V internalRemove(Object key) {
    var rest = _rest;
    if (rest == null) return null;
    var bucket = _getBucket(rest, key);
    int index = internalFindBucketIndex(bucket, key);
    if (index < 0) return null;
    // Use splice to remove the [cell] element at the index and
    // unlink the cell before returning its value.
    LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
    _unlinkCell(cell);
    // TODO(kasperl): Consider getting rid of the bucket list when
    // the length reaches zero.
    return JS('', '#', cell.hashMapCellValue);
  }

  void clear() {
    if (_length > 0) {
      _strings = _nums = _rest = _first = _last = null;
      _length = 0;
      _modified();
    }
  }

  void forEach(void action(K key, V value)) {
    LinkedHashMapCell cell = _first;
    int modifications = _modifications;
    while (cell != null) {
      K key = JS('', '#', cell.hashMapCellKey);
      V value = JS('', '#', cell.hashMapCellValue);
      action(key, value);
      if (modifications != _modifications) {
        throw new ConcurrentModificationError(this);
      }
      cell = cell._next;
    }
  }

  void _addHashTableEntry(var table, K key, V value) {
    LinkedHashMapCell cell = _getTableCell(table, key);
    if (cell == null) {
      _setTableEntry(table, key, _newLinkedCell(key, value));
    } else {
      cell.hashMapCellValue = value;
    }
  }

  V _removeHashTableEntry(var table, Object key) {
    if (table == null) return null;
    LinkedHashMapCell cell = _getTableCell(table, key);
    if (cell == null) return null;
    _unlinkCell(cell);
    _deleteTableEntry(table, key);
    return JS('', '#', cell.hashMapCellValue);
  }

  void _modified() {
    // 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.
    _modifications = (_modifications + 1) & 0x3ffffff;
  }

  // Create a new cell and link it in as the last one in the list.
  LinkedHashMapCell _newLinkedCell(K key, V value) {
    LinkedHashMapCell cell = new LinkedHashMapCell(key, value);
    if (_first == null) {
      _first = _last = cell;
    } else {
      LinkedHashMapCell last = _last;
      cell._previous = last;
      _last = last._next = cell;
    }
    _length++;
    _modified();
    return cell;
  }

  // Unlink the given cell from the linked list of cells.
  void _unlinkCell(LinkedHashMapCell cell) {
    LinkedHashMapCell previous = cell._previous;
    LinkedHashMapCell next = cell._next;
    if (previous == null) {
      assert(cell == _first);
      _first = next;
    } else {
      previous._next = next;
    }
    if (next == null) {
      assert(cell == _last);
      _last = previous;
    } else {
      next._previous = previous;
    }
    _length--;
    _modified();
  }

  static bool _isStringKey(var key) {
    return key is String;
  }

  static bool _isNumericKey(var key) {
    // Only treat unsigned 30-bit integers as numeric keys. This way,
    // we avoid converting them to strings when we use them as keys in
    // the JavaScript hash table object.
    return key is num && JS('bool', '(# & 0x3ffffff) === #', key, key);
  }

  int internalComputeHashCode(var key) {
    // We force the hash codes to be unsigned 30-bit integers to avoid
    // issues with problematic keys like '__proto__'. Another option
    // would be to throw an exception if the hash code isn't a number.
    return JS('int', '# & 0x3ffffff', key.hashCode);
  }

  List<LinkedHashMapCell> _getBucket(var table, var key) {
    var hash = internalComputeHashCode(key);
    return _getTableBucket(table, hash);
  }

  int internalFindBucketIndex(var bucket, var key) {
    if (bucket == null) return -1;
    int length = JS('int', '#.length', bucket);
    for (int i = 0; i < length; i++) {
      LinkedHashMapCell cell = JS('var', '#[#]', bucket, i);
      if (cell.hashMapCellKey == key) return i;
    }
    return -1;
  }

  String toString() => MapBase.mapToString(this);

  LinkedHashMapCell _getTableCell(var table, var key) {
    return JS('var', '#[#]', table, key);
  }

  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
    return JS('var', '#[#]', table, key);
  }

  void _setTableEntry(var table, var key, var value) {
    assert(value != null);
    JS('void', '#[#] = #', table, key, value);
  }

  void _deleteTableEntry(var table, var key) {
    JS('void', 'delete #[#]', table, key);
  }

  bool _containsTableEntry(var table, var key) {
    LinkedHashMapCell cell = _getTableCell(table, key);
    return cell != null;
  }

  _newHashTable() {
    // Create a new JavaScript object to be used as a hash table. Use
    // Object.create to avoid the properties on Object.prototype
    // showing up as entries.
    var table = JS('var', 'Object.create(null)');
    // Attempt to force the hash table into 'dictionary' mode by
    // adding a property to it and deleting it again.
    var temporaryKey = '<non-identifier-key>';
    _setTableEntry(table, temporaryKey, table);
    _deleteTableEntry(table, temporaryKey);
    return table;
  }
}

class Es6LinkedHashMap<K, V> extends JsLinkedHashMap<K, V> {
  @override
  LinkedHashMapCell _getTableCell(var table, var key) {
    return JS('var', '#.get(#)', table, key);
  }

  @override
  List<LinkedHashMapCell> _getTableBucket(var table, var key) {
    return JS('var', '#.get(#)', table, key);
  }

  @override
  void _setTableEntry(var table, var key, var value) {
    JS('void', '#.set(#, #)', table, key, value);
  }

  @override
  void _deleteTableEntry(var table, var key) {
    JS('void', '#.delete(#)', table, key);
  }

  @override
  bool _containsTableEntry(var table, var key) {
    return JS('bool', '#.has(#)', table, key);
  }

  @override
  _newHashTable() {
    return JS('var', 'new Map()');
  }
}

class LinkedHashMapCell {
  final dynamic hashMapCellKey;
  dynamic hashMapCellValue;

  LinkedHashMapCell _next;
  LinkedHashMapCell _previous;

  LinkedHashMapCell(this.hashMapCellKey, this.hashMapCellValue);
}

class LinkedHashMapKeyIterable<E> extends EfficientLengthIterable<E> {
  final dynamic _map;
  LinkedHashMapKeyIterable(this._map);

  int get length => _map._length;
  bool get isEmpty => _map._length == 0;

  Iterator<E> get iterator {
    return new LinkedHashMapKeyIterator<E>(_map, _map._modifications);
  }

  bool contains(Object element) {
    return _map.containsKey(element);
  }

  void forEach(void f(E element)) {
    LinkedHashMapCell cell = _map._first;
    int modifications = _map._modifications;
    while (cell != null) {
      f(JS('', '#', cell.hashMapCellKey));
      if (modifications != _map._modifications) {
        throw new ConcurrentModificationError(_map);
      }
      cell = cell._next;
    }
  }
}

class LinkedHashMapKeyIterator<E> implements Iterator<E> {
  final dynamic _map;
  final int _modifications;
  LinkedHashMapCell _cell;
  E _current;

  LinkedHashMapKeyIterator(this._map, this._modifications) {
    _cell = _map._first;
  }

  E get current => _current;

  bool moveNext() {
    if (_modifications != _map._modifications) {
      throw new ConcurrentModificationError(_map);
    } else if (_cell == null) {
      _current = null;
      return false;
    } else {
      _current = JS('', '#', _cell.hashMapCellKey);
      _cell = _cell._next;
      return true;
    }
  }
}
