// 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 'helper_classes.dart';

// Typed as dynamic to also test spreading a value of type dynamic.
final dynamic list = [1, 2, 3, 4];
final dynamic map = {1: 1, 2: 2, 3: 3, 4: 4};
final dynamic set = {1, 2, 3, 4};

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

void testList() {
  // Only spread.
  Expect.listEquals(list, <int>[...list]);

  // Spread at beginning.
  Expect.listEquals(list, <int>[
    ...<int>[1, 2],
    3,
    4,
  ]);

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

  // Spread at end.
  Expect.listEquals(list, <int>[
    1,
    2,
    ...<int>[3, 4],
  ]);

  // Empty spreads.
  Expect.listEquals(list, <int>[
    ...<int>[],
    1,
    2,
    ...<int>[],
    3,
    4,
    ...<int>[],
  ]);

  // Multiple spreads.
  Expect.listEquals(list, <int>[
    ...<int>[1],
    2,
    ...<int>[3, 4],
  ]);

  // Nested spreads.
  Expect.listEquals(list, <int>[
    ...<int>[
      ...<int>[1, 2],
      ...<int>[3, 4],
    ],
  ]);

  // Null-aware.
  var list23 = [2, 3] as List<int>?;
  var list4 = [4] as List<int>?;
  Expect.listEquals(list, <int>[1, ...?list23, ...?(null), ...?list4]);

  // Does not deep flatten.
  var innerList = <int>[3];
  Expect.listEquals(
    <Object>[1, 2, innerList, 4],
    <Object>[
      1,
      ...<Object>[2, innerList, 4],
    ],
  );

  // Downcast element from dynamic.
  Expect.listEquals(list, <int>[
    ...<dynamic>[1, 2, 3, 4],
  ]);
}

void testMap() {
  // Only spread.
  Expect.mapEquals(map, <int, int>{...map});

  // Spread at beginning.
  Expect.mapEquals(map, <int, int>{
    ...<int, int>{1: 1, 2: 2},
    3: 3,
    4: 4,
  });

  // Spread in middle.
  Expect.mapEquals(map, <int, int>{
    1: 1,
    ...<int, int>{2: 2, 3: 3},
    4: 4,
  });

  // Spread at end.
  Expect.mapEquals(map, <int, int>{
    1: 1,
    2: 2,
    ...<int, int>{3: 3, 4: 4},
  });

  // Empty spreads.
  Expect.mapEquals(map, <int, int>{
    ...<int, int>{},
    1: 1,
    2: 2,
    ...<int, int>{},
    3: 3,
    4: 4,
    ...<int, int>{},
  });

  // Multiple spreads.
  Expect.mapEquals(map, <int, int>{
    ...<int, int>{1: 1},
    2: 2,
    ...<int, int>{3: 3, 4: 4},
  });

  // Nested spreads.
  Expect.mapEquals(map, <int, int>{
    ...<int, int>{
      ...<int, int>{1: 1, 2: 2},
      ...<int, int>{3: 3, 4: 4},
    },
  });

  // Null-aware.
  var map23 = {2: 2, 3: 3} as Map<int, int>?;
  var map4 = {4: 4} as Map<int, int>?;
  Expect.mapEquals(map, <int, int>{1: 1, ...?map23, ...?(null), ...?map4});

  // Does not deep flatten.
  var innerMap = <int, int>{3: 3};
  Expect.mapEquals(
    <int, Object>{1: 1, 2: 2, 3: innerMap, 4: 4},
    <int, Object>{
      1: 1,
      ...<int, Object>{2: 2, 3: innerMap, 4: 4},
    },
  );

  // Downcast element from dynamic.
  Expect.mapEquals(map, <int, int>{
    ...<dynamic, dynamic>{1: 1, 2: 2, 3: 3, 4: 4},
  });
}

void testSet() {
  // Only spread.
  Expect.setEquals(set, <int>{...set});

  // Spread at beginning.
  Expect.setEquals(set, <int>{
    ...<int>[1, 2],
    3,
    4,
  });

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

  // Spread at end.
  Expect.setEquals(set, <int>{
    1,
    2,
    ...<int>[3, 4],
  });

  // Empty spreads.
  Expect.setEquals(set, <int>{...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]});

  // Multiple spreads.
  Expect.setEquals(set, <int>{
    ...<int>[1],
    2,
    ...<int>[3, 4],
  });

  // Nested spreads.
  Expect.setEquals(set, <int>{
    ...<int>{
      ...<int>[1, 2],
      ...<int>[3, 4],
    },
  });

  // Null-aware.
  var list23 = [2, 3] as List<int>?;
  var list4 = [4] as List<int>?;
  Expect.setEquals(set, <int>{1, ...?list23, ...?(null), ...?list4});

  // Does not deep flatten.
  var innerSet = <int>{3};
  Expect.setEquals(
    <Object>{1, 2, innerSet, 4},
    <Object>{
      1,
      ...<Object>[2, innerSet, 4],
    },
  );

  // Downcast element from dynamic.
  Expect.setEquals(set, <int>{
    ...<dynamic>[1, 2, 3, 4],
  });
}

void testDuplicateKeys() {
  Expect.mapEquals(map, <int, int>{
    1: 1,
    2: 2,
    ...<int, int>{2: 2, 3: 3, 4: 4},
    ...<int, int>{3: 3},
    4: 4,
  });
  Expect.setEquals(set, <int>{
    1,
    2,
    ...<int>[1, 2, 3, 4],
    ...<int>[2, 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 map = <Equality, int>{
    e1a: 1,
    ...<Equality, int>{e1b: 2, e2a: 3, e2b: 4},
  };
  Expect.equals("1:a,2:a", map.keys.join(","));

  var set = <Equality>{
    e1a,
    ...<Equality>[e1b, e2a, e2b],
  };
  Expect.equals("1:a,2:a", set.join(","));

  // All elements are evaluated, left to right.
  var transcript = <String>[];
  T log<T>(T value) {
    transcript.add(value.toString());
    return value;
  }

  map = <Equality, int>{
    log(e1a): log(1),
    ...<Equality, int>{log(e1b): log(2), log(e2a): log(3), log(e2b): log(4)},
  };
  Expect.equals("1:a,1,1:b,2,2:a,3,2:b,4", transcript.join(","));

  transcript.clear();
  set = <Equality>{
    log(e1a),
    ...<Equality>[log(e1b), log(e2a), log(e2b)],
  };
  Expect.equals("1:a,1:b,2:a,2:b", transcript.join(","));
}
