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

/// A specialized double-linked list of elements that extends [LinkedListEntry].
///
/// This is not a generic data structure. It only accepts elements that *extend*
/// the [LinkedListEntry] class. See the [Queue] implementations for generic
/// collections that allow constant time adding and removing at the ends.
///
/// This is not a [List] implementation. Despite its name, this class does not
/// implement the [List] interface. It does not allow constant time lookup by
/// index.
///
/// Because the elements themselves contain the links of this linked list,
/// each element can be in only one list at a time. To add an element to another
/// list, it must first be removed from its current list (if any).
/// For the same reason, the [remove] and [contains] methods
/// are based on *identity*, even if the [LinkedListEntry] chooses
/// to override [Object.==].
///
/// In return, each element knows its own place in the linked list, as well as
/// which list it is in. This allows constant time
/// [LinkedListEntry.insertAfter], [LinkedListEntry.insertBefore] and
/// [LinkedListEntry.unlink] operations when all you have is the element.
///
/// A `LinkedList` also allows constant time adding and removing at either end,
/// and a constant time length getter.
///
/// Example:
/// ```dart
/// class EntryItem extends LinkedListEntry<EntryItem> {
///   final int id;
///   final String text;
///   EntryItem(this.id, this.text);
///
///   @override
///   String toString() {
///     return '$id : $text';
///   }
/// }
///
/// void main(){
///   final linkedList = LinkedList<EntryItem>();
///   linkedList.addAll(
///       [EntryItem(1, 'A'), EntryItem(2, 'B'), EntryItem(3, 'C')]);
///   print(linkedList.first); // 1 : A
///   print(linkedList.last); // 3 : C
///
///   // Add new item after first item.
///   linkedList.first.insertAfter(EntryItem(15, 'E'));
///   // Add new item before last item.
///   linkedList.last.insertBefore(EntryItem(10, 'D'));
///   // Iterate items.
///   for (var entry in linkedList) {
///     print(entry);
///     // 1 : A
///     // 15 : E
///     // 2 : B
///     // 10 : D
///     // 3 : C
///   }
///
///   // Remove item using index from list.
///   linkedList.elementAt(2).unlink();
///   print(linkedList); // (1 : A, 15 : E, 10 : D, 3 : C)
///   // Remove first item.
///   linkedList.first.unlink();
///   print(linkedList); // (15 : E, 10 : D, 3 : C)
///   // Remove last item from list.
///   linkedList.remove(linkedList.last);
///   print(linkedList); // (15 : E, 10 : D)
///   // Remove all items.
///   linkedList.clear();
///   print(linkedList.length); // 0
///   print(linkedList.isEmpty); // true
/// }
/// ```
class LinkedList<E extends LinkedListEntry<E>> extends Iterable<E> {
  int _modificationCount = 0;
  int _length = 0;
  E? _first;

  /// Constructs a new empty linked list.
  LinkedList();

  /// Adds [entry] to the beginning of the linked list.
  void addFirst(E entry) {
    _insertBefore(_first, entry, updateFirst: true);
    _first = entry;
  }

  /// Adds [entry] to the end of the linked list.
  void add(E entry) {
    _insertBefore(_first, entry, updateFirst: false);
  }

  /// Adds [entries] to the end of the linked list.
  void addAll(Iterable<E> entries) {
    entries.forEach(add);
  }

  /// Removes [entry] from the linked list.
  ///
  /// Returns false and does nothing if [entry] is not in this linked list.
  ///
  /// This is equivalent to calling `entry.unlink()` if the entry is in this
  /// list.
  bool remove(E entry) {
    if (entry._list != this) return false;
    _unlink(entry); // Unlink will decrement length.
    return true;
  }

  /// Whether [entry] is a [LinkedListEntry] belonging to this list.
  ///
  /// The [entry] is considered as belonging to this list if
  /// its [LinkedListEntry.list] is this list.
  bool contains(Object? entry) =>
      entry is LinkedListEntry && identical(this, entry.list);

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

  int get length => _length;

  /// Remove all elements from this linked list.
  void clear() {
    _modificationCount++;
    if (isEmpty) return;

    E next = _first!;
    do {
      E entry = next;
      next = entry._next!;
      entry._next = entry._previous = entry._list = null;
    } while (!identical(next, _first));

    _first = null;
    _length = 0;
  }

  E get first {
    if (isEmpty) {
      throw StateError('No such element');
    }
    return _first!;
  }

  E get last {
    if (isEmpty) {
      throw StateError('No such element');
    }
    return _first!._previous!;
  }

  E get single {
    if (isEmpty) {
      throw StateError('No such element');
    }
    if (_length > 1) {
      throw StateError('Too many elements');
    }
    return _first!;
  }

  /// Call [action] with each entry in this linked list.
  ///
  /// It's an error if [action] modifies the linked list.
  void forEach(void action(E entry)) {
    int modificationCount = _modificationCount;
    if (isEmpty) return;

    E current = _first!;
    do {
      action(current);
      if (modificationCount != _modificationCount) {
        throw ConcurrentModificationError(this);
      }
      current = current._next!;
    } while (!identical(current, _first));
  }

  bool get isEmpty => _length == 0;

  /// Inserts [newEntry] as last entry of the list.
  ///
  /// If [updateFirst] is true and [entry] is the first entry in the list,
  /// updates the [_first] field to point to the [newEntry] as first entry.
  void _insertBefore(E? entry, E newEntry, {required bool updateFirst}) {
    if (newEntry.list != null) {
      throw StateError('LinkedListEntry is already in a LinkedList');
    }
    _modificationCount++;

    newEntry._list = this;
    if (isEmpty) {
      assert(entry == null);
      newEntry._previous = newEntry._next = newEntry;
      _first = newEntry;
      _length++;
      return;
    }
    E predecessor = entry!._previous!;
    E successor = entry;
    newEntry._previous = predecessor;
    newEntry._next = successor;
    predecessor._next = newEntry;
    successor._previous = newEntry;
    if (updateFirst && identical(entry, _first)) {
      _first = newEntry;
    }
    _length++;
  }

  void _unlink(E entry) {
    _modificationCount++;
    entry._next!._previous = entry._previous;
    E? next = entry._previous!._next = entry._next;
    _length--;
    entry._list = entry._next = entry._previous = null;
    if (isEmpty) {
      _first = null;
    } else if (identical(entry, _first)) {
      _first = next;
    }
  }
}

class _LinkedListIterator<E extends LinkedListEntry<E>> implements Iterator<E> {
  final LinkedList<E> _list;
  final int _modificationCount;
  E? _current;
  E? _next;
  bool _visitedFirst;

  _LinkedListIterator(LinkedList<E> list)
      : _list = list,
        _modificationCount = list._modificationCount,
        _next = list._first,
        _visitedFirst = false;

  E get current => _current as E;

  bool moveNext() {
    if (_modificationCount != _list._modificationCount) {
      throw ConcurrentModificationError(this);
    }
    if (_list.isEmpty || (_visitedFirst && identical(_next, _list.first))) {
      _current = null;
      return false;
    }
    _visitedFirst = true;
    _current = _next;
    _next = _next!._next;
    return true;
  }
}

/// An object that can be an element in a [LinkedList].
///
/// All elements of a `LinkedList` must extend this class.
/// The class provides the internal links that link elements together
/// in the `LinkedList`, and a reference to the linked list itself
/// that an element is currently part of.
///
/// An entry can be in at most one linked list at a time.
/// While an entry is in a linked list, the [list] property points to that
/// linked list, and otherwise the `list` property is `null`.
///
/// When created, an entry is not in any linked list.
abstract class LinkedListEntry<E extends LinkedListEntry<E>> {
  LinkedList<E>? _list;
  E? _next;
  E? _previous;

  /// The linked list containing this element.
  ///
  /// The value is `null` if this entry is not currently in any list.
  LinkedList<E>? get list => _list;

  /// Unlink the element from its linked list.
  ///
  /// The entry must currently be in a linked list when this method is called.
  void unlink() {
    _list!._unlink(this as E);
  }

  /// The successor of this element in its linked list.
  ///
  /// The value is `null` if there is no successor in the linked list,
  /// or if this entry is not currently in any list.
  E? get next {
    if (_list == null || identical(_list!.first, _next)) return null;
    return _next;
  }

  /// The predecessor of this element in its linked list.
  ///
  /// The value is `null` if there is no predecessor in the linked list,
  /// or if this entry is not currently in any list.
  E? get previous {
    if (_list == null || identical(this, _list!.first)) return null;
    return _previous;
  }

  /// Insert an element after this element in this element's linked list.
  ///
  /// This entry must be in a linked list when this method is called.
  /// The [entry] must not be in a linked list.
  void insertAfter(E entry) {
    _list!._insertBefore(_next, entry, updateFirst: false);
  }

  /// Insert an element before this element in this element's linked list.
  ///
  /// This entry must be in a linked list when this method is called.
  /// The [entry] must not be in a linked list.
  void insertBefore(E entry) {
    _list!._insertBefore(this as E, entry, updateFirst: true);
  }
}
