// Copyright (c) 2014, 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.

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

class MyList extends ListBase {
  List list;
  MyList(this.list);

  get length => list.length;
  set length(val) { list.length = val; }

  operator [](index) => list[index];
  operator []=(index, val) => list[index] = val;
}

id(x) => x;

main() {
  // Test functionality.
  for (var iterable in [
      const [1, 2, 3],
      [1, 2, 3],
      new List(3)..[0] = 1..[1] = 2..[2] = 3,
      {1: 1, 2: 2, 3: 3}.keys,
      {1: 1, 2: 2, 3: 3}.values,
      new Iterable.generate(3, (x) => x + 1),
      new List.generate(3, (x) => x + 1),
      [0, 1, 2, 3].where((x) => x > 0),
      [0, 1, 2].map((x) => x + 1),
      [[1, 2], [3]].expand(id),
      [3, 2, 1].reversed,
      [0, 1, 2, 3].skip(1),
      [1, 2, 3, 4].take(3),
      new Uint8List(3)..[0] = 1..[1] = 2..[2] = 3,
      (new HashMap()..[1] = 1..[2] = 2..[3] = 3).keys,
      (new HashMap()..[1] = 1..[2] = 2..[3] = 3).values,
      (new SplayTreeMap()..[1] = 0..[2] = 0..[3] = 0).keys,
      (new SplayTreeMap()..[0] = 1..[1] = 2..[2] = 3).values,
      new HashSet()..add(1)..add(2)..add(3),
      new LinkedHashSet()..add(1)..add(2)..add(3),
      new SplayTreeSet()..add(1)..add(2)..add(3),
      "\x01\x02\x03".codeUnits,
      "\x01\x02\x03".runes,
      new MyList([1, 2, 3]),
    ]) {
    int callCount = 0;
    var result = iterable.reduce((x, y) { callCount++;  return x + y; });
    Expect.equals(6, result, "${iterable.runtimeType}");
    Expect.equals(2, callCount);
  }

  // Empty iterables not allowed.
  for (var iterable in [
      const [],
      [],
      new List(0),
      {}.keys,
      {}.values,
      new Iterable.generate(0, (x) => x + 1),
      new List.generate(0, (x) => x + 1),
      [0, 1, 2, 3].where((x) => false),
      [].map((x) => x + 1),
      [[], []].expand(id),
      [].reversed,
      [0, 1, 2, 3].skip(4),
      [1, 2, 3, 4].take(0),
      new Uint8List(0),
      (new HashMap()).keys,
      (new HashMap()).values,
      (new SplayTreeMap()).keys,
      (new SplayTreeMap()).values,
      new HashSet(),
      new LinkedHashSet(),
      new SplayTreeSet(),
      "".codeUnits,
      "".runes,
      new MyList([]),
    ]) {
    Expect.throws(() { iterable.reduce((x, y) => throw "Unreachable"); },
                  (e) => e is StateError);
  }

  // Singleton iterables not calling reduce function.
  for (var iterable in [
      const [1],
      [1],
      new List(1)..[0] = 1,
      {1: 1}.keys,
      {1: 1}.values,
      new Iterable.generate(1, (x) => x + 1),
      new List.generate(1, (x) => x + 1),
      [0, 1, 2, 3].where((x) => x == 1),
      [0].map((x) => x + 1),
      [[], [1]].expand(id),
      [1].reversed,
      [0, 1].skip(1),
      [1, 2, 3, 4].take(1),
      new Uint8List(1)..[0] = 1,
      (new HashMap()..[1] = 0).keys,
      (new HashMap()..[0] = 1).values,
      (new SplayTreeMap()..[1] = 0).keys,
      (new SplayTreeMap()..[0] = 1).values,
      new HashSet()..add(1),
      new LinkedHashSet()..add(1),
      new SplayTreeSet()..add(1),
      "\x01".codeUnits,
      "\x01".runes,
      new MyList([1]),
    ]) {
    Expect.equals(1, iterable.reduce((x, y) => throw "Unreachable"));
  }

  // Concurrent modifications not allowed.
  testModification(base, modify, transform) {
    var iterable = transform(base);
    Expect.throws(() {
      iterable.reduce((x, y) {
        modify(base);
        return x + y;
      });
    }, (e) => e is ConcurrentModificationError);
  }

  void add4(collection) { collection.add(4); }
  void put4(map) { map[4] = 4; }

  testModification([1, 2, 3], add4, id);
  testModification(new HashSet()..add(1)..add(2)..add(3), add4, id);
  testModification(new LinkedHashSet()..add(1)..add(2)..add(3), add4, id);
  testModification(new SplayTreeSet()..add(1)..add(2)..add(3), add4, id);
  testModification(new MyList([1, 2, 3]), add4, id);

  testModification([0, 1, 2, 3], add4, (x) => x.where((x) => x > 0));
  testModification([0, 1, 2], add4, (x) => x.map((x) => x + 1));
  testModification([[1, 2], [3]], add4, (x) => x.expand((x) => x));
  testModification([3, 2, 1], add4, (x) => x.reversed);
  testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.keys);
  testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.values);
  var hashMap = new HashMap()..[1] = 1..[2] = 2..[3] = 3;
  testModification(hashMap, put4, (x) => x.keys);
  hashMap = new HashMap()..[1] = 1..[2] = 2..[3] = 3;
  testModification(hashMap, put4, (x) => x.values);
  var splayMap = new SplayTreeMap()..[1] = 1..[2] = 2..[3] = 3;
  testModification(splayMap, put4, (x) => x.keys);
  splayMap = new SplayTreeMap()..[1] = 1..[2] = 2..[3] = 3;
  testModification(splayMap, put4, (x) => x.values);
}
