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

/// A rudimentary linked list.
class LinkedList<T extends LinkedListEntry<T>> extends IterableBase<T> {
  T get first => _first as T;
  T? _first;

  T get last => _last as T;
  T? _last;

  int length = 0;

  bool get isEmpty => length == 0;

  /**
   * Adds [newLast] to the end of this linked list.
   */
  void add(T newLast) {
    assert(newLast._next == null && newLast._previous == null);
    if (_last != null) {
      assert(_last!._next == null);
      _last!._next = newLast;
    } else {
      _first = newLast;
    }
    newLast._previous = _last;
    _last = newLast;
    _last!._list = this;
    length++;
  }

  /**
   * Adds [newFirst] to the beginning of this linked list.
   */
  void addFirst(T newFirst) {
    if (_first != null) {
      assert(_first!._previous == null);
      _first!._previous = newFirst;
    } else {
      _last = newFirst;
    }
    newFirst._next = _first;
    _first = newFirst;
    _first!._list = this;
    length++;
  }

  /**
   * Removes the given [node] from this list.
   *
   * If the entry is not in this linked list nothing happens.
   *
   * Also see [LinkedListEntry.unlink].
   */
  void remove(T node) {
    if (node._list != this) return;
    length--;
    if (node._previous == null) {
      assert(identical(node, _first));
      _first = node._next;
    } else {
      node._previous!._next = node._next;
    }
    if (node._next == null) {
      assert(identical(node, _last));
      _last = node._previous;
    } else {
      node._next!._previous = node._previous;
    }
    node._next = node._previous = null;
    node._list = null;
  }

  Iterator<T> get iterator => new _LinkedListIterator<T>(this);
}

class LinkedListEntry<T extends LinkedListEntry<T>> {
  T? _next;
  T? _previous;
  LinkedList<T>? _list;

  /**
   * Unlinks the element from its linked list.
   *
   * If the entry is not in a linked list, does nothing. Otherwise, this
   * is equivalent to calling [LinkedList.remove] on the list this entry
   * is currently in.
   */
  void unlink() {
    _list?.remove(this as T);
  }
}

class _LinkedListIterator<T extends LinkedListEntry<T>> implements Iterator<T> {
  /// The current element of the iterator.
  T? _current;
  T get current => _current as T;

  /// The list the iterator iterates over.
  ///
  /// Set to [null] if the provided list was empty (indicating that there were
  /// no entries to iterate over).
  ///
  /// Set to [null] as soon as [moveNext] was invoked (indicating that the
  /// iterator has to work with [current] from now on.
  LinkedList<T>? _list;

  _LinkedListIterator(LinkedList<T> list) : _list = list {
    if (list.length == 0) _list = null;
  }

  bool moveNext() {
    // current is null if the iterator hasn't started iterating, or if the
    // iteration is finished. In the first case, the [_list] field is not null.
    if (_current == null) {
      var list = _list;
      if (list == null) return false;
      assert(list.length > 0);
      _current = list.first;
      _list = null;
      return true;
    }
    _current = _current!._next;
    return _current != null;
  }
}
