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

/// @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<int>(0, (int prev, element) => prev + element as int));

  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<int>(0, (int prev, element) => prev + element as int));

  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<int>(0, (int prev, element) => prev + element as int));

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