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

// @dart = 2.9

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(Object value) {
      return (value as int) ~/ 10;
    }

    bool is10(Object 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(Object value) {
      return (value is int);
    }

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

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

    bool is1(Object 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(Object 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(Object value) {
      sum += value as int;
    }

    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();
}
