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

// @dart = 2.9

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(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 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(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
        .throwsStateError(() => iterable.reduce((x, y) => throw "Unreachable"));
  }

  // Singleton iterables not calling reduce function.
  for (dynamic 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 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);
}
