// 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);

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

    bool is10(int 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.equals(true, queue.any(is10));

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

    Expect.equals(true, queue.every(isInstanceOfInt));

    Expect.equals(false, queue.every(is10));

    bool is1(int value) {
      return (value == 1);
    }
    Expect.equals(false, queue.any(is1));

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

    var exception = null;
    try {
      queue.removeFirst();
    } on StateError catch (e) {
      exception = e;
    }
    Expect.equals(true, exception != null);
    Expect.equals(0, queue.length);

    exception = null;
    try {
      queue.removeLast();
    } on StateError catch (e) {
      exception = e;
    }
    Expect.equals(true, exception != null);
    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(int value) {
      return (value > 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(int value) {
      sum += value;
    }
    queue.forEach(sumElements);
    Expect.equals(expectedSum, sum);
  }

  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(e) { sum += e; };

    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) => null);
    emptyQueue.retainWhere((x) => null);
  }

  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.equals(true, !identical(entry1, entry2));
      entry1 = entry1.nextEntry();
      entry2 = entry2.nextEntry();
    }
    Expect.equals(null, 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(queue1.toList(), [4, 1, 5, 6, 2, 7, 8, 3, 9]);
    Expect.equals(1, firstEntry.remove());
    Expect.equals(2, secondEntry.remove());
    Expect.equals(3, thirdEntry.remove());
    Expect.equals(6, queue1.length);
    Expect.listEquals(queue1.toList(), [4, 5, 6, 7, 8, 9]);
  }
}

void linkEntryTest() {
  var entry = new DoubleLinkedQueueEntry(42);
  Expect.equals(null, entry.previousEntry());
  Expect.equals(null, 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.equals(null, next.nextEntry());
  Expect.equals(null, 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.equals(null, next.nextEntry());
  Expect.equals(null, prev.previousEntry());
  Expect.equals(37, next.element);
  Expect.equals(87, prev.element);

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

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


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