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

// @dart = 2.7

import "package:expect/expect.dart";
import 'dart:collection';
import 'package:compiler/src/util/setlet.dart';

main() {
  for (int i = 1; i <= 32; i++) {
    test(i);
  }

  testAllLikeSet();
}

test(int size) {
  var setlet = new Setlet();
  for (int i = 0; i < size; i++) {
    Expect.isTrue(setlet.isEmpty == (i == 0));
    setlet.add(i);
    Expect.equals(i + 1, setlet.length);
    Expect.isFalse(setlet.isEmpty);
    for (int j = 0; j < size + size; j++) {
      Expect.isTrue(setlet.contains(j) == (j <= i));
    }
    Expect.isTrue(setlet.remove(i));
    Expect.isFalse(setlet.remove(i + 1));
    setlet.add(i);

    List expectedElements = [];
    for (int j = 0; j <= i; j++) expectedElements.add(j);

    List actualElements = [];
    setlet.forEach((each) => actualElements.add(each));
    Expect.listEquals(expectedElements, actualElements);

    actualElements = [];
    for (var each in setlet) actualElements.add(each);
    Expect.listEquals(expectedElements, actualElements);
  }

  for (int i = 0; i < size; i++) {
    Expect.equals(size, setlet.length);

    // Try removing all possible ranges one by one and re-add them.
    for (int k = size; k > i; --k) {
      for (int j = i; j < k; j++) {
        Expect.isTrue(setlet.remove(j));
        int expectedSize = size - (j - i + 1);
        Expect.equals(expectedSize, setlet.length);
        Expect.isFalse(setlet.remove(j));
        Expect.isFalse(setlet.contains(j));

        Expect.isFalse(setlet.contains(null));
        setlet.add(null);
        Expect.equals(expectedSize + 1, setlet.length);
        Expect.isTrue(setlet.contains(null));
        Expect.isTrue(setlet.remove(null));
        Expect.equals(expectedSize, setlet.length);
        Expect.isFalse(setlet.remove(null));
      }

      for (int j = i; j < k; j++) {
        setlet.add(j);
      }
    }

    Expect.equals(size, setlet.length);
    Expect.isTrue(setlet.contains(i));
  }
}

testAllLikeSet() {
  // For a variety of inputs and operations, test that Setlet behaves just like
  // Set.
  var samples = [
    [],
    [1],
    [1, 2],
    [2, 1],
    [1, 3],
    [3, 1],
    [1, 2, 3],
    [3, 1, 2],
    [1, 2, 3, 4, 5, 6, 7],
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [6, 7, 8, 9, 10, 11],
    [7, 8, 6, 5],
  ];

  for (var a in samples) {
    for (var b in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) {
      testSetXElement('add', (s, e) => s.add(e), a, b);
      testSetXElement('remove', (s, e) => s.remove(e), a, b);
      testSetXElement('contains', (s, e) => s.contains(e), a, b);
      testSetXElement('lookup', (s, e) => s.lookup(e), a, b);
    }
  }

  for (var a in samples) {
    for (var b in samples) {
      testSetXSet('addAll', (s, t) => s.addAll(t), a, b);
      testSetXSet('removeAll', (s, t) => s.removeAll(t), a, b);
      testSetXSet('retainAll', (s, t) => s.retainAll(t), a, b);
      testSetXSet('containsAll', (s, t) => s.containsAll(t), a, b);
      testSetXSet('union', (s, t) => s.union(t), a, b);
      testSetXSet('intersection', (s, t) => s.intersection(t), a, b);
      testSetXSet('difference', (s, t) => s.difference(t), a, b);
    }
  }
}

testSetXElement(name, fn, a, b) {
  var set1 = new LinkedHashSet.from(a);
  var setlet1 = new Setlet.from(a);

  var setResult = fn(set1, b);
  var setletResult = fn(setlet1, b);

  var operationName = '$name $a $b';
  checkResult(operationName, setResult, setletResult);
  checkModifications(operationName, set1, setlet1);
}

testSetXSet(name, fn, a, b) {
  var set1 = new LinkedHashSet.from(a);
  var set2 = new LinkedHashSet.from(b);
  var setlet1 = new Setlet.from(a);
  var setlet2 = new Setlet.from(b);

  var setResult = fn(set1, set2);
  var setletResult = fn(setlet1, setlet2);

  var operationName = '$name $a $b';
  checkResult(operationName, setResult, setletResult);
  checkModifications(operationName, set1, setlet1);
}

checkResult(operationName, setResult, setletResult) {
  if (setResult == null || setResult is bool || setResult is num) {
    Expect.equals(setResult, setletResult, '$operationName');
  } else if (setResult is Iterable) {
    Expect.isTrue(setletResult is Iterable, '$operationName: returns Iterable');
    Expect.equals(setResult.isEmpty, setletResult.isEmpty,
        '$operationName: same isEmpty');
    Expect.equals(
        setResult.length, setletResult.length, '$operationName: same length');
    Expect.listEquals(setResult.toList(), setletResult.toList(),
        '$operationName: same toList() result');
  } else {
    Expect.isFalse(true, '$operationName: unexpected result type');
  }
}

checkModifications(operationName, setReceiver, setletReceiver) {
  Expect.equals(setReceiver.length, setletReceiver.length,
      '$operationName: same post-operation receiver length');
  Expect.listEquals(setReceiver.toList(), setletReceiver.toList(),
      '$operationName: same post-operation receiver contents');
}
