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

Iterable id(Iterable x) => x;

main() {
  // Test functionality.
  for (dynamic iterable in [
    const [1, 2, 3],
    [1, 2, 3],
    new List<int?>.filled(3, null)
      ..[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 type of reduce() callback should match element type.
      return (x + y) as int;
    });
    Expect.equals(6, result, "${iterable.runtimeType}");
    Expect.equals(2, callCount);
  }

  // Empty iterables not allowed.
  for (var iterable in [
    const [],
    [],
    new List.empty(),
    {}.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
        .throwsStateError(() => iterable.reduce((x, y) => throw "Unreachable"));
  }

  // Singleton iterables not calling reduce function.
  for (dynamic iterable in [
    const [1],
    [1],
    new List.filled(1, 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 type of reduce() callback should match element type.
        return (x + y) as int;
      });
    }, (e) => e is ConcurrentModificationError);
  }

  void add4(collection) {
    collection.add(4);
  }

  void addListOf4(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((int x) => x > 0));
  testModification([0, 1, 2], add4, (x) => x.map((x) => x + 1));
  testModification([
    [1, 2],
    [3]
  ], addListOf4, (x) => x.expand((List<int> 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);
}
