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

library queue.test;

import "package:expect/expect.dart";
import 'dart:collection';

abstract class QueueTest {
  Queue newQueue();
  Queue newQueueFrom(Iterable iterable);

  void testMain() {
    Queue queue = newQueue();
    checkQueue(queue, 0, 0);

    queue.addFirst(1);
    checkQueue(queue, 1, 1);

    queue.addLast(10);
    checkQueue(queue, 2, 11);

    Expect.equals(10, queue.removeLast());
    checkQueue(queue, 1, 1);

    queue.addLast(10);
    Expect.equals(1, queue.removeFirst());
    checkQueue(queue, 1, 10);

    queue.addFirst(1);
    queue.addLast(100);
    queue.addLast(1000);
    Expect.equals(1000, queue.removeLast());
    queue.addLast(1000);
    checkQueue(queue, 4, 1111);

    queue.removeFirst();
    checkQueue(queue, 3, 1110);

    dynamic mapTest(dynamic value) {
      return (value as int) ~/ 10;
    }

    bool is10(dynamic value) {
      return (value == 10);
    }

    Queue mapped = newQueueFrom(queue.map(mapTest));
    checkQueue(mapped, 3, 111);
    checkQueue(queue, 3, 1110);
    Expect.equals(1, mapped.removeFirst());
    Expect.equals(100, mapped.removeLast());
    Expect.equals(10, mapped.removeFirst());

    Queue other = newQueueFrom(queue.where(is10));
    checkQueue(other, 1, 10);

    Expect.isTrue(queue.any(is10));

    bool isInstanceOfInt(dynamic value) {
      return (value is int);
    }

    Expect.isTrue(queue.every(isInstanceOfInt));

    Expect.isFalse(queue.every(is10));

    bool is1(dynamic value) {
      return (value == 1);
    }

    Expect.isFalse(queue.any(is1));

    queue.clear();
    Expect.equals(0, queue.length);

    Expect.throws<StateError>(queue.removeFirst);
    Expect.equals(0, queue.length);

    Expect.throws<StateError>(queue.removeLast);
    Expect.equals(0, queue.length);

    queue.addFirst(1);
    queue.addFirst(2);
    Expect.equals(2, queue.first);
    Expect.equals(1, queue.last);

    queue.addLast(3);
    Expect.equals(3, queue.last);
    bool isGreaterThanOne(dynamic value) {
      return ((value as int) > 1);
    }

    other = newQueueFrom(queue.where(isGreaterThanOne));
    checkQueue(other, 2, 5);

    // Cycle through values without ever having large element count.
    queue = newQueue();
    queue.add(0);
    for (int i = 0; i < 255; i++) {
      queue.add(i + 1);
      Expect.equals(i, queue.removeFirst());
    }
    Expect.equals(255, queue.removeFirst());
    Expect.isTrue(queue.isEmpty);

    testAddAll();
    testLengthChanges();
    testLarge();
    testFromListToList();
  }

  void checkQueue(Queue queue, int expectedSize, int expectedSum) {
    testLength(expectedSize, queue);
    int sum = 0;
    void sumElements(dynamic value) {
      sum += value as int;
    }

    queue.forEach(sumElements);
    Expect.equals(expectedSum, sum);
  }

  void testLength(int length, Queue queue) {
    Expect.equals(length, queue.length);
    ((length == 0) ? Expect.isTrue : Expect.isFalse)(queue.isEmpty);
    ((length != 0) ? Expect.isTrue : Expect.isFalse)(queue.isNotEmpty);
  }

  void testAddAll() {
    Set<int> set = new Set<int>.from([1, 2, 4]);
    Expect.equals(3, set.length);

    Queue queue1 = newQueueFrom(set);
    Queue queue2 = newQueue();
    Queue queue3 = newQueue();
    testLength(3, queue1);
    testLength(0, queue2);
    testLength(0, queue3);

    queue2.addAll(set);
    testLength(3, queue2);

    queue3.addAll(queue1);
    testLength(3, queue3);

    int sum = 0;
    void f(dynamic e) {
      sum += (e as int);
    }

    set.forEach(f);
    Expect.equals(7, sum);
    sum = 0;

    queue1.forEach(f);
    Expect.equals(7, sum);
    sum = 0;

    queue2.forEach(f);
    Expect.equals(7, sum);
    sum = 0;

    queue3.forEach(f);
    Expect.equals(7, sum);
    sum = 0;

    set = new Set<int>.from([]);
    queue1 = newQueueFrom(set);
    queue2 = newQueue();
    queue3 = newQueue();

    queue2.addAll(set);
    queue3.addAll(queue1);

    Expect.equals(0, set.length);
    Expect.equals(0, queue1.length);
    Expect.equals(0, queue2.length);
    Expect.equals(0, queue3.length);
  }

  void testLengthChanges() {
    // Test that the length property is updated properly by
    // modifications;
    Queue queue = newQueue();
    testLength(0, queue);

    for (int i = 1; i <= 10; i++) {
      queue.add(i);
      testLength(i, queue);
    }

    for (int i = 1; i <= 10; i++) {
      queue.addFirst(11 - i);
      testLength(10 + i, queue);
    }

    for (int i = 1; i <= 10; i++) {
      queue.addLast(i);
      testLength(20 + i, queue);
    }

    queue.addAll([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    testLength(40, queue);

    for (int i = 1; i <= 5; i++) {
      Expect.equals(i, queue.removeFirst());
      testLength(40 - i, queue);
    }

    for (int i = 1; i <= 5; i++) {
      Expect.equals(11 - i, queue.removeLast());
      testLength(35 - i, queue);
    }

    Expect.isTrue(queue.remove(10));
    testLength(29, queue);
    Expect.isFalse(queue.remove(999));
    testLength(29, queue);

    queue.removeWhere((x) => x == 7);
    testLength(26, queue);

    queue.retainWhere((x) => x != 3);
    testLength(23, queue);

    Expect.listEquals(
        [6, 8, 9, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 4, 5],
        queue.toList());

    // Regression test: http://dartbug.com/16270
    // These should all do nothing, and should not throw.
    Queue emptyQueue = newQueue();
    emptyQueue.remove(0);
    emptyQueue.removeWhere((x) => throw "unreachable");
    emptyQueue.retainWhere((x) => throw "unreachable");
    Expect.equals(0, emptyQueue.length);
  }

  void testLarge() {
    int N = 10000;
    Set set = new Set();

    Queue queue = newQueue();
    Expect.isTrue(queue.isEmpty);

    for (int i = 0; i < N; i++) {
      queue.add(i);
      set.add(i);
    }
    Expect.equals(N, queue.length);
    Expect.isFalse(queue.isEmpty);

    Expect.equals(0, queue.elementAt(0));
    Expect.equals(N - 1, queue.elementAt(N - 1));
    Expect.throws(() {
      queue.elementAt(-1);
    });
    Expect.throws(() {
      queue.elementAt(N);
    });

    Iterable skip1 = queue.skip(1);
    Iterable take1 = queue.take(1);
    Iterable mapped = queue.map((e) => -e);

    for (int i = 0; i < 500; i++) {
      Expect.equals(i, take1.first);
      Expect.equals(i, queue.first);
      Expect.equals(-i, mapped.first);
      Expect.equals(i + 1, skip1.first);
      Expect.equals(i, queue.removeFirst());
      Expect.equals(i + 1, take1.first);
      Expect.equals(-i - 1, mapped.first);
      Expect.equals(N - 1 - i, queue.last);
      Expect.equals(N - 1 - i, queue.removeLast());
    }
    Expect.equals(N - 1000, queue.length);

    Expect.isTrue(queue.remove(N >> 1));
    Expect.equals(N - 1001, queue.length);

    queue.clear();
    Expect.equals(0, queue.length);
    Expect.isTrue(queue.isEmpty);

    queue.addAll(set);
    Expect.equals(N, queue.length);
    Expect.isFalse(queue.isEmpty);

    // Iterate.
    for (var element in queue) {
      Expect.isTrue(set.contains(element));
    }

    queue.forEach((element) {
      Expect.isTrue(set.contains(element));
    });

    queue.addAll(set);
    Expect.equals(N * 2, queue.length);
    Expect.isFalse(queue.isEmpty);

    queue.clear();
    Expect.equals(0, queue.length);
    Expect.isTrue(queue.isEmpty);
  }

  void testFromListToList() {
    const int N = 256;
    List list = [];
    for (int i = 0; i < N; i++) {
      Queue queue = newQueueFrom(list);

      Expect.equals(list.length, queue.length);
      List to = queue.toList();
      Expect.listEquals(list, to);

      queue.add(i);
      list.add(i);
      Expect.equals(list.length, queue.length);
      to = queue.toList();
      Expect.listEquals(list, to);
    }
  }
}

class ListQueueTest extends QueueTest {
  Queue newQueue() => new ListQueue();
  Queue newQueueFrom(Iterable elements) => new ListQueue.from(elements);

  void testMain() {
    super.testMain();
    trickyTest();
  }

  void trickyTest() {
    // Test behavior around the know growing capacities of a ListQueue.
    Queue q = new ListQueue();

    for (int i = 0; i < 255; i++) {
      q.add(i);
    }
    for (int i = 0; i < 128; i++) {
      Expect.equals(i, q.removeFirst());
    }
    q.add(255);
    for (int i = 0; i < 127; i++) {
      q.add(i);
    }

    Expect.equals(255, q.length);

    // Remove element at end of internal buffer.
    q.removeWhere((v) => v == 255);
    // Remove element at beginning of internal buffer.
    q.removeWhere((v) => v == 0);
    // Remove element at both ends of internal buffer.
    q.removeWhere((v) => v == 254 || v == 1);

    Expect.equals(251, q.length);

    Iterable i255 = new Iterable.generate(255, (x) => x);

    q = new ListQueue();
    q.addAll(i255);
    Expect.listEquals(i255.toList(), q.toList());

    q = new ListQueue();
    q.addAll(i255.toList());
    Expect.listEquals(i255.toList(), q.toList());

    q = new ListQueue.from(i255);
    for (int i = 0; i < 128; i++) q.removeFirst();
    q.add(256);
    q.add(0);
    q.addAll(i255.toList());
    Expect.equals(129 + 255, q.length);

    // Test addAll that requires the queue to grow.
    q = new ListQueue();
    q.addAll(i255.take(35));
    q.addAll(i255.skip(35).take(96));
    q.addAll(i255.skip(35 + 96));
    Expect.listEquals(i255.toList(), q.toList());
  }
}

class DoubleLinkedQueueTest extends QueueTest {
  Queue newQueue() => new DoubleLinkedQueue();
  Queue newQueueFrom(Iterable elements) => new DoubleLinkedQueue.from(elements);

  void testMain() {
    super.testMain();
    testQueueElements();
  }

  void testQueueElements() {
    DoubleLinkedQueue<int> queue1 = new DoubleLinkedQueue<int>.from([1, 2, 3]);
    DoubleLinkedQueue<int> queue2 = new DoubleLinkedQueue<int>();
    queue2.addAll(queue1);

    Expect.equals(queue1.length, queue2.length);
    DoubleLinkedQueueEntry<int>? entry1 = queue1.firstEntry();
    DoubleLinkedQueueEntry<int>? entry2 = queue2.firstEntry();
    while (entry1 != null) {
      Expect.notIdentical(entry1, entry2);
      entry1 = entry1.nextEntry();
      entry2 = entry2!.nextEntry();
    }
    Expect.isNull(entry2);

    var firstEntry = queue1.firstEntry()!;
    var secondEntry = queue1.firstEntry()!.nextEntry()!;
    var thirdEntry = queue1.lastEntry()!;
    firstEntry.prepend(4);
    firstEntry.append(5);
    secondEntry.prepend(6);
    secondEntry.append(7);
    thirdEntry.prepend(8);
    thirdEntry.append(9);
    Expect.equals(9, queue1.length);
    Expect.listEquals([4, 1, 5, 6, 2, 7, 8, 3, 9], queue1.toList());
    Expect.equals(1, firstEntry.remove());
    Expect.equals(2, secondEntry.remove());
    Expect.equals(3, thirdEntry.remove());
    Expect.equals(6, queue1.length);
    Expect.listEquals([4, 5, 6, 7, 8, 9], queue1.toList());

    var elements = [];
    queue1.forEachEntry((entry) {
      elements.add(entry.element);
      entry.remove(); // Can remove while iterating.
    });
    Expect.listEquals([4, 5, 6, 7, 8, 9], elements);
    Expect.isTrue(queue1.isEmpty);
  }
}

void linkEntryTest() {
  var entry = new DoubleLinkedQueueEntry(42);
  Expect.isNull(entry.previousEntry());
  Expect.isNull(entry.nextEntry());

  entry.append(37);
  entry.prepend(87);
  var prev = entry.previousEntry()!;
  var next = entry.nextEntry()!;
  Expect.equals(42, entry.element);
  Expect.equals(37, next.element);
  Expect.equals(87, prev.element);
  Expect.identical(entry, prev.nextEntry());
  Expect.identical(entry, next.previousEntry());
  Expect.isNull(next.nextEntry());
  Expect.isNull(prev.previousEntry());

  entry.element = 117;
  Expect.equals(117, entry.element);
  Expect.identical(next, entry.nextEntry());
  Expect.identical(prev, entry.previousEntry());

  Expect.equals(117, entry.remove());
  Expect.identical(next, prev.nextEntry());
  Expect.identical(prev, next.previousEntry());
  Expect.isNull(next.nextEntry());
  Expect.isNull(prev.previousEntry());
  Expect.equals(37, next.element);
  Expect.equals(87, prev.element);

  Expect.equals(37, next.remove());
  Expect.equals(87, prev.element);
  Expect.isNull(prev.nextEntry());
  Expect.isNull(prev.previousEntry());

  Expect.equals(87, prev.remove());
}

main() {
  new DoubleLinkedQueueTest().testMain();
  new ListQueueTest().testMain();
  linkEntryTest();
}
