// 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.

  @override
  Queue<R> cast<R>() => throw UnimplementedError('Iterable.cast');

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

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

  @override
  bool get isEmpty => _head == _tail;

  @override
  bool get isNotEmpty => !isEmpty;

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

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

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

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

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

  @override
  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.

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

  @override
  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);
      }
    }
  }

  @override
  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;
  }

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

  @override
  String toString() => Iterable.iterableToFullString(this, '{', '}');

  // Queue interface.

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

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

  @override
  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;
  }

  @override
  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

  @override
  Never any(_) => throw UnimplementedError();
  @override
  Never contains(_) => throw UnimplementedError();
  @override
  Never every(_) => throw UnimplementedError();
  @override
  Never expand<T>(_) => throw UnimplementedError();
  @override
  Never firstWhere(_, {E Function()? orElse}) => throw UnimplementedError();
  @override
  Never fold<T>(_, _) => throw UnimplementedError();
  @override
  Never followedBy(_) => throw UnimplementedError();
  @override
  Never join([String _ = '']) => throw UnimplementedError();
  @override
  Never lastWhere(_, {E Function()? orElse}) => throw UnimplementedError();
  @override
  Never map<T>(_) => throw UnimplementedError();
  @override
  Never reduce(_) => throw UnimplementedError();
  @override
  Never singleWhere(_, {E Function()? orElse}) => throw UnimplementedError();
  @override
  Never skip(_) => throw UnimplementedError();
  @override
  Never skipWhile(_) => throw UnimplementedError();
  @override
  Never take(_) => throw UnimplementedError();
  @override
  Never takeWhile(_) => throw UnimplementedError();
  @override
  Never toSet() => throw UnimplementedError();
  @override
  Never where(_) => throw UnimplementedError();
  @override
  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;

  @override
  E get current => _current as E;

  @override
  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');
}
