// 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 "core_patch.dart";

// This function takes care of rehashing of the expandos in [objects]. We
// do this eagerly after snapshot deserialization.
@pragma("vm:entry-point", "call")
void _rehashObjects(List objects) {
  final int length = objects.length;
  for (int i = 0; i < length; ++i) {
    objects[i]._rehash();
  }
}

@patch
@pragma("vm:entry-point")
class Expando<T> {
  @patch
  Expando([String? name])
      : name = name,
        _data = new List<_WeakProperty?>.filled(_minSize, null),
        _used = 0;

  static const _minSize = 8;
  static final _deletedEntry = new _WeakProperty();

  @patch
  T? operator [](Object object) {
    _checkType(object);

    var mask = _size - 1;
    var idx = object._identityHashCode & mask;
    var wp = _data[idx];

    while (wp != null) {
      if (identical(wp.key, object)) {
        return unsafeCast<T?>(wp.value);
      } else if (wp.key == null) {
        // This entry has been cleared by the GC.
        _data[idx] = _deletedEntry;
      }
      idx = (idx + 1) & mask;
      wp = _data[idx];
    }

    return null;
  }

  @patch
  void operator []=(Object object, T? value) {
    _checkType(object);

    var mask = _size - 1;
    var idx = object._identityHashCode & mask;
    var empty_idx = -1;
    var wp = _data[idx];

    while (wp != null) {
      if (identical(wp.key, object)) {
        if (value != null) {
          // Update the associated value.
          wp.value = value;
        } else {
          // Mark the entry as deleted.
          _data[idx] = _deletedEntry;
        }
        return;
      } else if ((empty_idx < 0) && identical(wp, _deletedEntry)) {
        empty_idx = idx; // Insert at this location if not found.
      } else if (wp.key == null) {
        // This entry has been cleared by the GC.
        _data[idx] = _deletedEntry;
        if (empty_idx < 0) {
          empty_idx = idx; // Insert at this location if not found.
        }
      }
      idx = (idx + 1) & mask;
      wp = _data[idx];
    }

    if (value == null) {
      // Not entering a null value. We just needed to make sure to clear an
      // existing value if it existed.
      return;
    }

    if (empty_idx >= 0) {
      // We will be reusing the empty slot below.
      _used--;
      idx = empty_idx;
    }

    if (_used < _limit) {
      var ephemeron = new _WeakProperty();
      ephemeron.key = object;
      ephemeron.value = value;
      _data[idx] = ephemeron;
      _used++;
      return;
    }

    // Grow/reallocate if too many slots have been used.
    _rehash();
    this[object] = value; // Recursively add the value.
  }

  _rehash() {
    // Determine the population count of the map to allocate an appropriately
    // sized map below.
    var count = 0;
    var old_data = _data;
    var len = old_data.length;
    for (var i = 0; i < len; i++) {
      var entry = old_data[i];
      if ((entry != null) && (entry.key != null)) {
        // Only count non-cleared entries.
        count++;
      }
    }

    var new_size = _size;
    if (count <= (new_size >> 2)) {
      new_size = new_size >> 1;
    } else if (count > (new_size >> 1)) {
      new_size = new_size << 1;
    }
    new_size = (new_size < _minSize) ? _minSize : new_size;

    // Reset the mappings to empty so that we can just add the existing
    // valid entries.
    _data = new List<_WeakProperty?>.filled(new_size, null);
    _used = 0;

    for (var i = 0; i < old_data.length; i++) {
      var entry = old_data[i];
      if (entry != null) {
        // Ensure that the entry.key is not cleared between checking for it and
        // inserting it into the new table.
        var val = entry.value;
        var key = entry.key;
        if (key != null) {
          this[key] = val;
        }
      }
    }
  }

  static _checkType(object) {
    if ((object == null) ||
        (object is bool) ||
        (object is num) ||
        (object is String) ||
        (object is Pointer) ||
        (object is Struct) ||
        (object is Union)) {
      throw new ArgumentError.value(object,
          "Expandos are not allowed on strings, numbers, booleans, null, Pointers, Structs or Unions.");
    }
  }

  int get _size => _data.length;
  int get _limit => (3 * (_size ~/ 4));

  List<_WeakProperty?> _data;
  int _used; // Number of used (active and deleted) slots.
}

@patch
class WeakReference<T extends Object> {
  @patch
  factory WeakReference(T object) {
    final weakProperty = _WeakProperty()..key = object;
    return _WeakReferenceImpl<T>(weakProperty);
  }
}

class _WeakReferenceImpl<T extends Object> implements WeakReference<T> {
  // TODO(http://dartbug.com/48162): Implement _WeakReference in the VM
  // instead of reusing WeakProperty.
  final _WeakProperty _weakProperty;

  _WeakReferenceImpl(this._weakProperty);

  T? get target => _weakProperty.key as T?;
}

@patch
class Finalizer<T> {
  @patch
  factory Finalizer(void Function(T) object) {
    throw UnimplementedError("Finalizer");
  }
}
