// Copyright (c) 2019, 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 'utils.dart';

final list = [1, 2, 3, 4];
final map = {1: 1, 2: 2, 3: 3, 4: 4};
final set = {1, 2, 3, 4};

void main() {
  testList();
  testMap();
  testSet();
  testDuplicateKeys();
  testKeyOrder();
  testRuntimeErrors();
}

void testList() {
  // Only for.
  Expect.listEquals(list, <int>[for (var i in list) i]);

  // For at beginning.
  Expect.listEquals(list, <int>[for (var i in <int>[1, 2]) i, 3, 4]);

  // For in middle.
  Expect.listEquals(list, <int>[1, for (var i in <int>[2, 3]) i, 4]);

  // For at end.
  Expect.listEquals(list, <int>[1, 2, for (var i in <int>[3, 4]) i]);

  // Empty for.
  Expect.listEquals(list,
      <int>[1, for (var i in <int>[]) i, 2, 3, for (; false;) 9, 4]);

  // Multiple fors.
  Expect.listEquals(list,
      <int>[for (var i in <int>[1]) i, 2, for (var i = 3; i <= 4; i++) i]);

  // Spread inside for.
  Expect.listEquals(list,
      <int>[for (var i in <int>[0, 2]) ...<int>[1 + i, 2 + i]]);

  // If inside for.
  Expect.listEquals(list,
      <int>[for (var i in <int>[1, 9, 2, 3, 9, 4]) if (i != 9) i]);

  // Else inside for.
  Expect.listEquals(list,
      <int>[for (var i in <int>[1, -2, 3, -4]) if (i < 0) -i else i]);

  // For inside for.
  Expect.listEquals(list,
      <int>[for (var i in <int>[0, 2]) for (var j = 1; j <= 2; j++) i + j]);

  // Does not flatten nested collection literal.
  Expect.listEquals([1], [for (var i = 1; i < 2; i++) [i]].first);
  Expect.mapEquals({1: 1}, [for (var i = 1; i < 2; i++) {i: i}].first);
  Expect.setEquals({1}, [for (var i = 1; i < 2; i++) {i}].first);

  // Downcast iterable.
  Object obj = <int>[1, 2, 3, 4];
  Expect.listEquals(list, <int>[for (var n in obj) n]);

  // Downcast variable.
  Expect.listEquals(list, <int>[for (int n in <num>[1, 2, 3, 4]) n]);

  // Downcast element.
  Expect.listEquals(list, <int>[for (num n in <num>[1, 2, 3, 4]) n]);

  // Downcast condition.
  Expect.listEquals([1], <int>[for (var i = 1; (i < 2) as dynamic; i++) i]);
  Expect.listEquals([1], <int>[for (var i = 1; (i < 2) as Object; i++) i]);
}

void testMap() {
  // Only for.
  Expect.mapEquals(map, <int, int>{for (var i in list) i: i});

  // For at beginning.
  Expect.mapEquals(map,
      <int, int>{for (var i in <int>[1, 2]) i: i, 3: 3, 4: 4});

  // For in middle.
  Expect.mapEquals(map,
      <int, int>{1: 1, for (var i in <int>[2, 3]) i: i, 4: 4});

  // For at end.
  Expect.mapEquals(map,
      <int, int>{1: 1, 2: 2, for (var i in <int>[3, 4]) i: i});

  // Empty for.
  Expect.mapEquals(map, <int, int>{
    1: 1,
    for (var i in <int>[]) i: i,
    2: 2,
    3: 3,
    for (; false;) 9: 9,
    4: 4
  });

  // Multiple fors.
  Expect.mapEquals(map, <int, int>{
    for (var i in <int>[1]) i: i,
    2: 2,
    for (var i = 3; i <= 4; i++) i: i
  });

  // Spread inside for.
  Expect.mapEquals(map, <int, int>{
    for (var i in <int>[0, 2]) ...<int, int>{1 + i: 1 + i, 2 + i: 2 + i}
  });

  // If inside for.
  Expect.mapEquals(map,
      <int, int>{for (var i in <int>[1, 9, 2, 3, 9, 4]) if (i != 9) i: i});

  // Else inside for.
  Expect.mapEquals(map,
      <int, int>{for (var i in <int>[1, -2, 3, -4]) if (i < 0) -i: -i else i: i});

  // For inside for.
  Expect.mapEquals(map, <int, int>{
    for (var i in <int>[0, 2]) for (var j = 1; j <= 2; j++) i + j: i + j
  });

  // Downcast iterable.
  Object obj = <int>[1, 2, 3, 4];
  Expect.mapEquals(map, <int, int>{for (var n in obj) n: n});

  // Downcast variable.
  Expect.mapEquals(map, <int, int>{for (int n in <num>[1, 2, 3, 4]) n: n});

  // Downcast element.
  Expect.mapEquals(map, <int, int>{for (num n in <num>[1, 2, 3, 4]) n: n});

  // Downcast condition.
  Expect.mapEquals({1 : 1},
      <int, int>{for (var i = 1; (i < 2) as dynamic; i++) i: i});
  Expect.mapEquals({1 : 1},
      <int, int>{for (var i = 1; (i < 2) as Object; i++) i: i});
}

void testSet() {
  // Only for.
  Expect.setEquals(set, <int>{for (var i in list) i});

  // For at beginning.
  Expect.setEquals(set, <int>{for (var i in <int>[1, 2]) i, 3, 4});

  // For in middle.
  Expect.setEquals(set, <int>{1, for (var i in <int>[2, 3]) i, 4});

  // For at end.
  Expect.setEquals(set, <int>{1, 2, for (var i in <int>[3, 4]) i});

  // Empty for.
  Expect.setEquals(set,
      <int>{1, for (var i in <int>[]) i, 2, 3, for (; false;) 9, 4});

  // Multiple fors.
  Expect.setEquals(set,
      <int>{for (var i in <int>[1]) i, 2, for (var i = 3; i <= 4; i++) i});

  // Spread inside for.
  Expect.setEquals(set,
      <int>{for (var i in <int>[0, 2]) ...<int>[1 + i, 2 + i]});

  // If inside for.
  Expect.setEquals(set,
      <int>{for (var i in <int>[1, 9, 2, 3, 9, 4]) if (i != 9) i});

  // Else inside for.
  Expect.setEquals(set,
      <int>{for (var i in <int>[1, -2, 3, -4]) if (i < 0) -i else i});

  // For inside for.
  Expect.setEquals(set,
      <int>{for (var i in <int>[0, 2]) for (var j = 1; j <= 2; j++) i + j});

  // Does not flatten nested collection literal.
  Expect.listEquals([1], {for (var i = 1; i < 2; i++) [i]}.first);
  Expect.mapEquals({1: 1}, {for (var i = 1; i < 2; i++) {i: i}}.first);
  Expect.setEquals({1}, {for (var i = 1; i < 2; i++) {i}}.first);

  // Downcast iterable.
  Object obj = <int>[1, 2, 3, 4];
  Expect.setEquals(set, <int>{for (var n in obj) n});

  // Downcast variable.
  Expect.setEquals(set, <int>{for (int n in <num>[1, 2, 3, 4]) n});

  // Downcast element.
  Expect.setEquals(set, <int>{for (num n in <num>[1, 2, 3, 4]) n});

  // Downcast condition.
  Expect.setEquals({1}, <int>{for (var i = 1; (i < 2) as dynamic; i++) i});
  Expect.setEquals({1}, <int>{for (var i = 1; (i < 2) as Object; i++) i});
}

void testDuplicateKeys() {
  Expect.mapEquals(map, <int, int>{
    1: 1,
    for (var i in <int>[1, 2, 3]) i: i,
    for (var i = 2; i <= 3; i++) i: i,
    3: 3,
    4: 4
  });
  Expect.setEquals(set, <int>{
    1,
    for (var i in <int>[1, 2, 3]) i,
    for (var i = 2; i <= 3; i++) i,
    3,
    4
  });
}

void testKeyOrder() {
  // First equal key wins.
  var e1a = Equality(1, "a");
  var e1b = Equality(1, "b");
  var e2a = Equality(2, "a");
  var e2b = Equality(2, "b");
  var keys = [e1b, e2a, e2b];
  var values = [2, 3, 4];

  var map = <Equality, int>{
    e1a: 1,
    for (var i = 0; i < keys.length; i++) keys[i]: values[i]
  };
  Expect.equals("1:a,2:a", map.keys.join(","));
  Expect.equals("2,4", map.values.join(","));

  var set = <Equality>{e1a, for (var i = 0; i < keys.length; i++) keys[i]};
  Expect.equals("1:a,2:a", set.join(","));
}

void testRuntimeErrors() {
  // Null iterable.
  Iterable<int> nullIterable = null;
  Expect.throwsNoSuchMethodError(() => <int>[for (var i in nullIterable) 1]);
  Expect.throwsNoSuchMethodError(
      () => <int, int>{for (var i in nullIterable) 1: 1});
  Expect.throwsNoSuchMethodError(() => <int>{for (var i in nullIterable) 1});
}
