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