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

// SharedOptions=--enable-experiment=set-literals,control-flow-collections,spread-collections

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 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 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 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(","));

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

void testRuntimeErrors() {
  // Non-bool condition expression.
  dynamic nonBool = 3;
  Expect.throwsTypeError(() => <int>[for (; nonBool;) 1]);
  Expect.throwsTypeError(() => <int, int>{for (; nonBool;) 1: 1});
  Expect.throwsTypeError(() => <int>{for (; nonBool;) 1});

  // Null condition expression.
  bool nullBool = null;
  Expect.throwsAssertionError(() => <int>[for (; nullBool;) 1]);
  Expect.throwsAssertionError(() => <int, int>{for (; nullBool;) 1: 1});
  Expect.throwsAssertionError(() => <int>{for (; nullBool;) 1});

  // Cast for variable.
  dynamic nonInt = "string";
  Expect.throwsTypeError(() => <int>[for (int i = nonInt; false;) 1]);
  Expect.throwsTypeError(() => <int, int>{for (int i = nonInt; false;) 1: 1});
  Expect.throwsTypeError(() => <int>{for (int i = nonInt; false;) 1});

  // Cast for-in variable.
  dynamic nonIterable = 3;
  Expect.throwsTypeError(() => <int>[for (int i in nonIterable) 1]);
  Expect.throwsTypeError(() => <int, int>{for (int i in nonIterable) 1: 1});
  Expect.throwsTypeError(() => <int>{for (int i in nonIterable) 1});

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

  // Wrong element type.
  Expect.throwsTypeError(() => <int>[for (var i = 0; i < 1; i++) nonInt]);
  Expect.throwsTypeError(
      () => <int, int>{for (var i = 0; i < 1; i++) nonInt: 1});
  Expect.throwsTypeError(
      () => <int, int>{for (var i = 0; i < 1; i++) 1: nonInt});
  Expect.throwsTypeError(() => <int>{for (var i = 0; i < 1; i++) nonInt});
}
