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

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

testRemove(base) {
  int length = base.length;
  for (int i = 0; i < length; i++) {
    Expect.isFalse(base.isEmpty);
    base.remove(base.first);
  }
  Expect.isTrue(base.isEmpty);
}

testRemoveAll(base, Iterable removes) {
  Set retained = new Set();
  for (var element in base) {
    if (!removes.contains(element)) {
      retained.add(element);
    }
  }
  String name = "$base.removeAll($removes) -> $retained";
  base.removeAll(removes);
  for (var value in base) {
    Expect.isFalse(removes.contains(value), "$name: Found $value");
  }
  for (var value in retained) {
    Expect.isTrue(base.contains(value), "$name: Found $value");
  }
}

testRetainAll(base, Iterable retains) {
  Set retained = new Set();
  for (var element in base) {
    if (retains.contains(element)) {
      retained.add(element);
    }
  }
  String name = "$base.retainAll($retains) -> $retained";
  base.retainAll(retains);
  for (var value in base) {
    Expect.isTrue(retains.contains(value), "$name: Found $value");
  }
  for (var value in retained) {
    Expect.isTrue(base.contains(value), "$name: Found $value");
  }
}

testRemoveWhere(base, bool test(value)) {
  Set retained = new Set();
  for (var element in base) {
    if (!test(element)) {
      retained.add(element);
    }
  }
  String name = "$base.removeWhere(...) -> $retained";
  base.removeWhere(test);
  for (var value in base) {
    Expect.isFalse(test(value), "$name: Found $value");
  }
  for (var value in retained) {
    Expect.isTrue(base.contains(value), "$name: Found $value");
  }
}

testRetainWhere(base, bool test(value)) {
  Set retained = new Set();
  for (var element in base) {
    if (test(element)) {
      retained.add(element);
    }
  }
  String name = "$base.retainWhere(...) -> $retained";
  base.retainWhere(test);
  for (var value in base) {
    Expect.isTrue(test(value), "$name: Found $value");
  }
  for (var value in retained) {
    Expect.isTrue(base.contains(value), "$name: Found $value");
  }
}

void main() {
  var collections = [
    [],
    [1],
    [2],
    [1, 2],
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    [1, 3, 5, 7, 9],
    [2, 4, 6, 8, 10]
  ];
  for (var base in collections) {
    for (var delta in collections) {
      testRemove(base.toList());
      testRemove(base.toSet());

      var deltaSet = delta.toSet();
      testRemoveWhere(base.toList(), deltaSet.contains);
      testRetainWhere(base.toList(), (e) => !deltaSet.contains(e));

      testRemoveAll(base.toSet(), delta);
      testRemoveAll(base.toSet(), deltaSet);
      testRetainAll(base.toSet(), delta);
      testRetainAll(base.toSet(), deltaSet);
      testRemoveWhere(base.toSet(), deltaSet.contains);
      testRetainWhere(base.toSet(), (e) => !deltaSet.contains(e));

      // Test the ListBase class's List implementation.
      testRemoveWhere(new MyList(base.toList()), deltaSet.contains);
      testRetainWhere(new MyList(base.toList()), (e) => !deltaSet.contains(e));
    }
  }
}

class MyList<E> extends ListBase<E> {
  List<E> _source;
  MyList(this._source);
  int get length => _source.length;
  void set length(int length) {
    _source.length = length;
  }

  E operator [](int index) => _source[index];
  void operator []=(int index, E value) {
    _source[index] = value;
  }
}
