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

/// @assertion IterableMixin<E> abstract class
/// This [Iterable] mixin implements all [Iterable] members except [iterator].
/// All other methods are implemented in terms of [iterator].
/// @description Checks that this class implements all methods of [Iterable]
/// except [Iterable.iterator]
/// @author kaigorodov

import "../../../Utils/expect.dart";
import "dart:collection";

class NaturalIterator implements Iterator<int> {
  int limit;
  int _current = 0;

  NaturalIterator(this.limit);

  bool moveNext() {
    if (_current < limit) {
      _current++;
      return true;
    } else {
      return false;
    }
  }

  int get current => _current;
}

class MyIterable extends Object with IterableMixin {
  int _limit;

  MyIterable(this._limit);

  Iterator<int> get iterator {
    return new NaturalIterator(_limit);
  }
}

void check0(MyIterable myIterable) {
  Expect.throws(() => myIterable.first, (e) => e is StateError);

  Expect.isTrue(myIterable.isEmpty);

  Expect.isFalse(myIterable.isNotEmpty);

  Expect.throws(() => myIterable.last, (e) => e is StateError);

  Expect.equals(0, myIterable.length);

  Expect.throws(() => myIterable.single, (e) => e is StateError);

  Expect.isFalse(myIterable.any((element) => true));

  Expect.isFalse(myIterable.contains(1));

  Expect.throws(() => myIterable.elementAt(0), (e) => e is RangeError);

  Expect.isTrue(myIterable.every((element) => true));

  Iterable expanded = myIterable.expand((var element) => [element]);
  Expect.isTrue(expanded.isEmpty);

  Expect.throws(() {
    myIterable.firstWhere((element) => true);
  }, (e) => e is StateError);

  Expect.equals(0, myIterable.fold(0, (prev, element) => prev + element));

  myIterable.forEach((e) {
    throw new Exception();
  });

  Expect.equals("", myIterable.join(","));

  Expect.throws(() {
    myIterable.lastWhere((element) => true);
  }, (e) => e is StateError);

  Expect.isTrue(myIterable.map((element) => element).isEmpty);

  // not documented
  Expect.throws(() {
    myIterable.reduce((value, element) => value + element);
  }, (e) => e is StateError);
//  Expect.equals(0, myIterable.reduce((value, element) => value + element));

  Expect.throws(() {
    myIterable.singleWhere((element) => true);
  }, (e) => e is StateError);

  Expect.isTrue(myIterable.skip(0).isEmpty);
  Expect.throws(() {
    myIterable.skip(-1);
  });

  Expect.isTrue(myIterable.skipWhile((element) => false).isEmpty);

  Expect.isTrue(myIterable.take(1).isEmpty);
  Expect.throws(() {
    myIterable.take(-1);
  });

  Expect.isTrue(myIterable.takeWhile((element) => true).isEmpty);

  Expect.isTrue(myIterable.toList().isEmpty);
  Expect.isTrue(myIterable.toList(growable: false).isEmpty);

  Expect.isTrue(myIterable.toSet().isEmpty);

  Expect.isTrue(myIterable.where((element) => true).isEmpty);
}

void check1(MyIterable myIterable) {
  Expect.equals(1, myIterable.first);

  Expect.isFalse(myIterable.isEmpty);

  Expect.isTrue(myIterable.isNotEmpty);

  Expect.equals(1, myIterable.last);

  Expect.equals(1, myIterable.length);

  Expect.equals(1, myIterable.single);

  Expect.isTrue(myIterable.any((element) => true));

  Expect.isTrue(myIterable.contains(1));

  Expect.equals(1, myIterable.elementAt(0));

  Expect.isTrue(myIterable.every((element) => true));

  Iterable expanded = myIterable.expand((var element) => [element]);
  Expect.equals(1, expanded.length);

  Expect.equals(1, myIterable.firstWhere((element) => true));

  Expect.equals(1, myIterable.fold(0, (prev, element) => prev + element));

  Expect.throws(() {
    myIterable.forEach((e) {
      throw new Exception();
    });
  });

  Expect.equals("1", myIterable.join(","));

  Expect.equals(1, myIterable.lastWhere((element) => true));

  Expect.isFalse(myIterable.map((element) => element).isEmpty);

  Expect.equals(1, myIterable.reduce((value, element) => value + element));

  Expect.equals(1, myIterable.singleWhere((element) => true));

  Expect.isFalse(myIterable.skip(0).isEmpty);
  Expect.throws(() {
    myIterable.skip(-1);
  });

  Expect.isFalse(myIterable.skipWhile((element) => false).isEmpty);

  Expect.isFalse(myIterable.take(1).isEmpty);
  Expect.throws(() {
    myIterable.take(-1);
  });

  Expect.isFalse(myIterable.takeWhile((element) => true).isEmpty);
  Expect.isTrue(myIterable.takeWhile((element) => false).isEmpty);

  Expect.isFalse(myIterable.toList().isEmpty);
  Expect.isFalse(myIterable.toList(growable: false).isEmpty);

  Expect.isFalse(myIterable.toSet().isEmpty);

  Expect.isFalse(myIterable.where((element) => true).isEmpty);
}

void check2(MyIterable myIterable) {
  Expect.equals(1, myIterable.first);

  Expect.isFalse(myIterable.isEmpty);

  Expect.isTrue(myIterable.isNotEmpty);

  Expect.equals(2, myIterable.last);

  Expect.equals(2, myIterable.length);

  Expect.throws(() => myIterable.single, (e) => e is StateError);

  Expect.isTrue(myIterable.any((element) => true));

  Expect.isTrue(myIterable.contains(2));

  Expect.equals(2, myIterable.elementAt(1));

  Expect.isTrue(myIterable.every((element) => true));

  Iterable expanded = myIterable.expand((var element) => [element]);
  Expect.equals(2, expanded.length);

  Expect.equals(1, myIterable.firstWhere((element) => true));

  Expect.equals(3, myIterable.fold(0, (prev, element) => prev + element));

  Expect.throws(() {
    myIterable.forEach((e) {
      throw new Exception();
    });
  });

  Expect.equals("1,2", myIterable.join(","));

  Expect.equals(2, myIterable.lastWhere((element) => true));

  Expect.isFalse(myIterable.map((element) => element).isEmpty);

  Expect.equals(3, myIterable.reduce((value, element) => value + element));

  Expect.throws(() {
    myIterable.singleWhere((element) => true);
  }, (e) => e is StateError);

  Expect.isFalse(myIterable.skip(0).isEmpty);
  Expect.throws(() {
    myIterable.skip(-1);
  });

  Expect.isFalse(myIterable.skipWhile((element) => false).isEmpty);

  Expect.isFalse(myIterable.take(1).isEmpty);
  Expect.throws(() {
    myIterable.take(-1);
  });

  Expect.isFalse(myIterable.takeWhile((element) => true).isEmpty);
  Expect.isTrue(myIterable.takeWhile((element) => false).isEmpty);

  Expect.isFalse(myIterable.toList().isEmpty);
  Expect.isFalse(myIterable.toList(growable: false).isEmpty);

  Expect.isFalse(myIterable.toSet().isEmpty);

  Expect.isFalse(myIterable.where((element) => true).isEmpty);
}

main() {
  check0(new MyIterable(0));
  check1(new MyIterable(1));
  check2(new MyIterable(2));
}
