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

// Invariance optimizations benchmark based on adding and removing from a copy
// of the default implementation of Queue.
//
// This benchmark incurs type checks due to parametric subtype covariance.  Many
// of these type checks can be optimized away by invariance analysis to discover
// which types are invariant.
//
// Some compilers already optimize '`this`-calls`, where the receiver is
// `this`. `this`-calls are a trivial kind of invariance since the caller and
// callee share the same receiver, so share the same class type variables. An
// example of this is when `ListQueue.add` calls `ListQueue._add`. There is no
// need to check `value as E` again.
//
// One example that is not well optimized at the time of writing is when type
// variables of related collections are invariant. The Queue implementation
// uses, as a backing store, a fixed length list that has a type invariant with
// respect to the `Queue<E>`, constructed via `List<E?>.filled(...)`.
//
// There are two axes of benchmark variation:
//   1. The queue element type (`int`, `int?`, `List<int>`, records)
//   2. Adding elements via `Queue.add` and `Queue.addAll`.
//
// The first axis exercises a variety of covariance checks. More complex checks
// tend to be slower, magnifying the benefit of invariance analysis.
//
// The second axis, using `add` and `addAll`, adds more opportunities for
// invariances to be detected (`_queue` and `_items` are separate collections
// that have the same value of the type variable).
//
// All benchmarks use the workload defined in `Benchmark<T>` so that the
// compilers don't achieve optimizations by flowing constant types. We avoid
// mixins because some implementations expand mixins, which could result in the
// expanded code having non-parametric types, e.g. `Queue<int>`.

import 'dart:typed_data';
import 'package:benchmark_harness/benchmark_harness.dart';

abstract class Benchmark<T> extends BenchmarkBase {
  final int _iterations;
  final Queue<T> _queue = Queue<T>();

  final bool _runAddAll;

  Benchmark(String name, String type, this._iterations)
    : _runAddAll = name.startsWith('addAll'),
      super('InvarianceQueue.$name.$type');

  // For the add/remove benchmarks, values are copied through this field. `T` is
  // invariant with respect to the Queue element type.
  T? _item;

  // For the addAll/remove benchmarks, values are copied through this second
  // Queue which contains one element at the time of copy.
  final Queue<T> _items = Queue<T>();

  @override
  void run() {
    if (_runAddAll) {
      runAddAllRemove();
    } else {
      runAddRemove();
    }
  }

  void check() {
    if (_runAddAll) {
      checkAddAllRemove();
    } else {
      checkAddRemove();
    }
  }

  void runAddRemove() {
    for (int i = 0; i < _iterations; i++) {
      _item = _queue.removeFirst();
      _queue.add(_item as T);
    }
  }

  void checkAddRemove() {
    if (_item == _queue.first) throw StateError('bad');
  }

  void runAddAllRemove() {
    for (int i = 0; i < _iterations; i++) {
      _items
        ..clear()
        ..add(_queue.removeFirst());
      _queue.addAll(_items);
    }
  }

  void checkAddAllRemove() {
    if (_items.single == _queue.first) throw StateError('bad');
  }
}

abstract class QueueInt extends Benchmark<int> {
  QueueInt(String name, int count) : super(name, 'int', count);
  @override
  void setup() {
    _queue
      ..clear()
      ..add(1)
      ..add(2)
      ..add(3)
      ..add(4);
  }
}

abstract class QueueIntQ extends Benchmark<int?> {
  QueueIntQ(String name, int count) : super(name, 'intQ', count);
  @override
  void setup() {
    _queue
      ..clear()
      ..add(1)
      ..add(2)
      ..add(3)
      ..add(null);
  }
}

abstract class QueueListInt extends Benchmark<List<int>> {
  QueueListInt(String name, int count) : super(name, 'List.int', count);
  @override
  void setup() {
    _queue
      ..clear()
      ..add('1'.codeUnits)
      ..add([2])
      ..add(Uint8List(3))
      ..add(Int16List(4));
  }
}

typedef SimpleRecord = (int, int);
typedef ComplexRecord = (num, num Function(num), {Comparable z});

abstract class QueueSimpleRecord extends Benchmark<SimpleRecord> {
  QueueSimpleRecord(String name, int count)
    : super(name, 'simple-record', count);
  @override
  void setup() {
    _queue
      ..clear()
      ..add((0, 1))
      ..add((1, 2))
      ..add((2, 3))
      ..add((3, 0));
  }
}

abstract class QueueComplexRecord extends Benchmark<ComplexRecord> {
  QueueComplexRecord(String name, int count)
    : super(name, 'complex-record', count);
  @override
  void setup() {
    _queue
      ..clear()
      ..add((1.2, 1.2.compareTo, z: 'x'))
      ..add((0, (x) => x + 1, z: 123))
      // Type depends on class type variable:
      ..add((1, Env<num>().foo, z: BigInt.parse('42')))
      // Type depends on function type variable:
      ..add((1, Env<num>().bar<int>(), z: DateTime.now()));
  }
}

class Env<T> {
  T foo(T x) => x;

  S Function(T) bar<S extends T>() {
    S localFunction(T x) {
      if (x is S) return x;
      throw 'bad';
    }

    return localFunction;
  }
}

class QueueAddRemoveInt extends QueueInt {
  QueueAddRemoveInt(int count) : super('add-remove', count);
}

class QueueAddRemoveIntQ extends QueueIntQ {
  QueueAddRemoveIntQ(int count) : super('add-remove', count);
}

class QueueAddRemoveListInt extends QueueListInt {
  QueueAddRemoveListInt(int count) : super('add-remove', count);
}

class QueueAddRemoveSimpleRecord extends QueueSimpleRecord {
  QueueAddRemoveSimpleRecord(int count) : super('add-remove', count);
}

class QueueAddRemoveComplexRecord extends QueueComplexRecord {
  QueueAddRemoveComplexRecord(int count) : super('add-remove', count);
}

class QueueAddAllRemoveInt extends QueueInt {
  QueueAddAllRemoveInt(int count) : super('addAll-remove', count);
}

class QueueAddAllRemoveIntQ extends QueueIntQ {
  QueueAddAllRemoveIntQ(int count) : super('addAll-remove', count);
}

class QueueAddAllRemoveListInt extends QueueListInt {
  QueueAddAllRemoveListInt(int count) : super('addAll-remove', count);
}

class QueueAddAllRemoveSimpleRecord extends QueueSimpleRecord {
  QueueAddAllRemoveSimpleRecord(int count) : super('addAll-remove', count);
}

class QueueAddAllRemoveComplexRecord extends QueueComplexRecord {
  QueueAddAllRemoveComplexRecord(int count) : super('addAll-remove', count);
}

void pollute() {
  // Pollute run size.
  QueueAddRemoveInt(0)
    ..setup()
    ..run();
  QueueAddRemoveIntQ(1)
    ..setup()
    ..run();
  QueueAddRemoveListInt(2)
    ..setup()
    ..run();
  // Further pollute type.
  Queue<String>()
    ..add('a')
    ..add('b')
    ..addAll({'a', 'b'})
    ..addAll(['a', 'b'])
    ..toString();
  Queue<Pattern>()
    ..add('a')
    ..add(RegExp('b'))
    ..toString();
  Queue<String Function(String)>()..add(Env<String>().foo);
  Queue<num>()
    ..addAll(<int>[1])
    ..addAll(<double>[2.3]);
}

void main() {
  final benchmarks = <Benchmark>[
    QueueAddRemoveInt(1000),
    QueueAddRemoveIntQ(1000),
    QueueAddRemoveListInt(1000),
    QueueAddRemoveSimpleRecord(1000),
    QueueAddRemoveComplexRecord(1000),
    QueueAddAllRemoveInt(1000),
    QueueAddAllRemoveIntQ(1000),
    QueueAddAllRemoveListInt(1000),
    QueueAddAllRemoveSimpleRecord(1000),
    QueueAddAllRemoveComplexRecord(1000),
  ];

  // Warmup all benchmarks to ensure JIT compilers see full polymorphism.
  for (final benchmark in benchmarks) {
    pollute();
    benchmark.setup();
  }

  for (final benchmark in benchmarks) {
    pollute();
    benchmark.warmup();
  }

  for (final benchmark in benchmarks) {
    // `report` calls `setup`, but `setup` is idempotent.
    benchmark.report();
    benchmark.check();
  }
}

/// What follows is a copy of the SDK Queue implementation, cut down to remove
/// methods that are unused in this benchmark.

/// A [Queue] is a collection that can be manipulated at both ends.
abstract interface class Queue<E> implements Iterable<E> {
  /// Creates a queue.
  factory Queue() = ListQueue<E>;

  /// Removes and returns the first element of this queue.
  E removeFirst();

  /// Removes and returns the last element of the queue.
  E removeLast();

  /// Adds [value] at the beginning of the queue.
  void addFirst(E value);

  /// Adds [value] at the end of the queue.
  void addLast(E value);

  /// Adds [value] at the end of the queue.
  void add(E value);

  /// Removes a single instance of [value] from the queue.
  ///
  /// Returns `true` if a value was removed, or `false` if the queue
  /// contained no element equal to [value].
  bool remove(Object? value);

  /// Adds all elements of [iterable] at the end of the queue. The
  /// length of the queue is extended by the length of [iterable].
  void addAll(Iterable<E> iterable);

  /// Removes all elements in the queue. The size of the queue becomes zero.
  void clear();
}

/// List based [Queue].
final class ListQueue<E> implements Queue<E> {
  static const int _INITIAL_CAPACITY = 8;
  List<E?> _table;
  int _head;
  int _tail;
  int _modificationCount = 0;

  /// Create an empty queue.
  ///
  /// If [initialCapacity] is given, prepare the queue for at least that many
  /// elements.
  ListQueue([int? initialCapacity])
    : _head = 0,
      _tail = 0,
      _table = List<E?>.filled(_calculateCapacity(initialCapacity), null);

  static int _calculateCapacity(int? initialCapacity) {
    if (initialCapacity == null || initialCapacity < _INITIAL_CAPACITY) {
      return _INITIAL_CAPACITY;
    } else if (!_isPowerOf2(initialCapacity)) {
      return _nextPowerOf2(initialCapacity);
    }
    assert(_isPowerOf2(initialCapacity));
    return initialCapacity;
  }

  // Iterable interface.

  Queue<R> cast<R>() => throw UnimplementedError('Iteratble.cast');

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

  void forEach(void f(E element)) {
    int modificationCount = _modificationCount;
    for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
      f(_table[i] as E);
      _checkModification(modificationCount);
    }
  }

  bool get isEmpty => _head == _tail;

  bool get isNotEmpty => !isEmpty;

  int get length => (_tail - _head) & (_table.length - 1);

  E get first {
    if (_head == _tail) throw IterableElementError.noElement();
    return _table[_head] as E;
  }

  E get last {
    if (_head == _tail) throw IterableElementError.noElement();
    return _table[(_tail - 1) & (_table.length - 1)] as E;
  }

  E get single {
    if (_head == _tail) throw IterableElementError.noElement();
    if (length > 1) throw IterableElementError.tooMany();
    return _table[_head] as E;
  }

  E elementAt(int index) {
    IndexError.check(index, length, indexable: this);
    return _table[(_head + index) & (_table.length - 1)] as E;
  }

  List<E> toList({bool growable = true}) {
    int mask = _table.length - 1;
    int length = (_tail - _head) & mask;
    if (length == 0) return List<E>.empty(growable: growable);

    var list = List<E>.filled(length, first, growable: growable);
    for (int i = 0; i < length; i++) {
      list[i] = _table[(_head + i) & mask] as E;
    }
    return list;
  }

  // Collection interface.

  void add(E value) {
    _add(value);
  }

  void addAll(Iterable<E> elements) {
    if (elements is List<E>) {
      List<E> list = elements;
      int addCount = list.length;
      int length = this.length;
      if (length + addCount >= _table.length) {
        _preGrow(length + addCount);
        // After preGrow, all elements are at the start of the list.
        _table.setRange(length, length + addCount, list, 0);
        _tail += addCount;
      } else {
        // Adding addCount elements won't reach _head.
        int endSpace = _table.length - _tail;
        if (addCount < endSpace) {
          _table.setRange(_tail, _tail + addCount, list, 0);
          _tail += addCount;
        } else {
          int preSpace = addCount - endSpace;
          _table.setRange(_tail, _tail + endSpace, list, 0);
          _table.setRange(0, preSpace, list, endSpace);
          _tail = preSpace;
        }
      }
      _modificationCount++;
    } else {
      for (E element in elements) _add(element);
    }
  }

  bool remove(Object? value) {
    for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
      E? element = _table[i];
      if (element == value) {
        _remove(i);
        _modificationCount++;
        return true;
      }
    }
    return false;
  }

  void clear() {
    if (_head != _tail) {
      for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
        _table[i] = null;
      }
      _head = _tail = 0;
      _modificationCount++;
    }
  }

  String toString() => Iterable.iterableToFullString(this, "{", "}");

  // Queue interface.

  void addLast(E value) {
    _add(value);
  }

  void addFirst(E value) {
    _head = (_head - 1) & (_table.length - 1);
    _table[_head] = value;
    if (_head == _tail) _grow();
    _modificationCount++;
  }

  E removeFirst() {
    if (_head == _tail) throw IterableElementError.noElement();
    _modificationCount++;
    E result = _table[_head] as E;
    _table[_head] = null;
    _head = (_head + 1) & (_table.length - 1);
    return result;
  }

  E removeLast() {
    if (_head == _tail) throw IterableElementError.noElement();
    _modificationCount++;
    _tail = (_tail - 1) & (_table.length - 1);
    E result = _table[_tail] as E;
    _table[_tail] = null;
    return result;
  }

  // Internal helper functions.

  /// Whether [number] is a power of two.
  ///
  /// Only works for positive numbers.
  static bool _isPowerOf2(int number) => (number & (number - 1)) == 0;

  /// Rounds [number] up to the nearest power of 2.
  ///
  /// If [number] is a power of 2 already, it is returned.
  ///
  /// Only works for positive numbers.
  static int _nextPowerOf2(int number) {
    assert(number > 0);
    number = (number << 1) - 1;
    for (;;) {
      int nextNumber = number & (number - 1);
      if (nextNumber == 0) return number;
      number = nextNumber;
    }
  }

  /// Check if the queue has been modified during iteration.
  void _checkModification(int expectedModificationCount) {
    if (expectedModificationCount != _modificationCount) {
      throw ConcurrentModificationError(this);
    }
  }

  /// Adds element at end of queue. Used by both [add] and [addAll].
  void _add(E element) {
    _table[_tail] = element;
    _tail = (_tail + 1) & (_table.length - 1);
    if (_head == _tail) _grow();
    _modificationCount++;
  }

  /// Removes the element at [offset] into [_table].
  ///
  /// Removal is performed by linearly moving elements either before or after
  /// [offset] by one position.
  ///
  /// Returns the new offset of the following element. This may be the same
  /// offset or the following offset depending on how elements are moved
  /// to fill the hole.
  int _remove(int offset) {
    int mask = _table.length - 1;
    int startDistance = (offset - _head) & mask;
    int endDistance = (_tail - offset) & mask;
    if (startDistance < endDistance) {
      // Closest to start.
      int i = offset;
      while (i != _head) {
        int prevOffset = (i - 1) & mask;
        _table[i] = _table[prevOffset];
        i = prevOffset;
      }
      _table[_head] = null;
      _head = (_head + 1) & mask;
      return (offset + 1) & mask;
    } else {
      _tail = (_tail - 1) & mask;
      int i = offset;
      while (i != _tail) {
        int nextOffset = (i + 1) & mask;
        _table[i] = _table[nextOffset];
        i = nextOffset;
      }
      _table[_tail] = null;
      return offset;
    }
  }

  /// Grow the table when full.
  void _grow() {
    List<E?> newTable = List<E?>.filled(_table.length * 2, null);
    int split = _table.length - _head;
    newTable.setRange(0, split, _table, _head);
    newTable.setRange(split, split + _head, _table, 0);
    _head = 0;
    _tail = _table.length;
    _table = newTable;
  }

  int _writeToList(List<E?> target) {
    assert(target.length >= length);
    if (_head <= _tail) {
      int length = _tail - _head;
      target.setRange(0, length, _table, _head);
      return length;
    } else {
      int firstPartSize = _table.length - _head;
      target.setRange(0, firstPartSize, _table, _head);
      target.setRange(firstPartSize, firstPartSize + _tail, _table, 0);
      return _tail + firstPartSize;
    }
  }

  /// Grows the table even if it is not full.
  void _preGrow(int newElementCount) {
    assert(newElementCount >= length);

    // Add some extra room to ensure that there's room for more elements after
    // expansion.
    newElementCount += newElementCount >> 1;
    int newCapacity = _nextPowerOf2(newElementCount);
    List<E?> newTable = List<E?>.filled(newCapacity, null);
    _tail = _writeToList(newTable);
    _table = newTable;
    _head = 0;
  }

  /// Unimplemented Iterable methods

  Never any(_) => throw UnimplementedError();
  Never contains(_) => throw UnimplementedError();
  Never every(_) => throw UnimplementedError();
  Never expand<T>(_) => throw UnimplementedError();
  Never firstWhere(_, {E orElse()?}) => throw UnimplementedError();
  Never fold<E>(_, _) => throw UnimplementedError();
  Never followedBy(_) => throw UnimplementedError();
  Never join([String _ = '']) => throw UnimplementedError();
  Never lastWhere(_, {E orElse()?}) => throw UnimplementedError();
  Never map<T>(_) => throw UnimplementedError();
  Never reduce(_) => throw UnimplementedError();
  Never singleWhere(_, {E orElse()?}) => throw UnimplementedError();
  Never skip(_) => throw UnimplementedError();
  Never skipWhile(_) => throw UnimplementedError();
  Never take(_) => throw UnimplementedError();
  Never takeWhile(_) => throw UnimplementedError();
  Never toSet() => throw UnimplementedError();
  Never where(_) => throw UnimplementedError();
  Never whereType<T>() => throw UnimplementedError();
}

/// Iterator for a [ListQueue].
///
/// Considers any add or remove operation a concurrent modification.
class _ListQueueIterator<E> implements Iterator<E> {
  final ListQueue<E> _queue;
  final int _end;
  final int _modificationCount;
  int _position;
  E? _current;

  _ListQueueIterator(ListQueue<E> queue)
    : _queue = queue,
      _end = queue._tail,
      _modificationCount = queue._modificationCount,
      _position = queue._head;

  E get current => _current as E;

  bool moveNext() {
    _queue._checkModification(_modificationCount);
    if (_position == _end) {
      _current = null;
      return false;
    }
    _current = _queue._table[_position];
    _position = (_position + 1) & (_queue._table.length - 1);
    return true;
  }
}

abstract class IterableElementError {
  static StateError noElement() => StateError("No element");
  static StateError tooMany() => StateError("Too many elements");
}
