// 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';

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

const dynamic dynamicTrue = true;
const Object objectTrue = true;

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

void testList() {
  // Then if true.
  Expect.identical(list, const <int>[1, if (true) 2, 3]);

  // Nothing if false and no else.
  Expect.identical(list, const <int>[1, if (false) 9, 2, 3]);

  // Else if false.
  Expect.identical(list, const <int>[1, if (false) 9 else 2, 3]);

  // Only if.
  Expect.identical(const [1], const <int>[if (true) 1]);

  // If at beginning.
  Expect.identical(list, const <int>[if (true) 1, 2, 3]);

  // If in middle.
  Expect.identical(list, const <int>[1, if (true) 2, 3]);

  // If at end.
  Expect.identical(list, const <int>[1, 2, if (true) 3]);

  // Multiple ifs.
  Expect.identical(list,
      const <int>[if (true) 1, if (false) 9, 2, if (true) 3]);

  // Cast condition.
  Expect.identical(const [1], const <int>[if (dynamicTrue) 1]);
  Expect.identical(const [1], const <int>[if (objectTrue) 1]);

  // Does not flatten nested collection literal.
  Expect.identical(const [1], const [if (true) [1]].first);
  Expect.identical(const {1: 1}, const [if (true) {1: 1}].first);
  Expect.identical(const {1}, const [if (true) {1}].first);

  // Nested spread.
  Expect.identical(list,
      const <int>[if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]]);

  // Nested if in then.
  Expect.identical(const [1],
      const <int>[if (true) if (true) 1, if (true) if (false) 9]);

  // Nested if in else.
  Expect.identical(const [1], const <int>[if (false) 9 else if (true) 1]);
}

void testMap() {
  // Then if true.
  Expect.identical(map, const <int, int>{1: 1, if (true) 2: 2, 3: 3});

  // Nothing if false and no else.
  Expect.identical(map, const <int, int>{1: 1, if (false) 9: 9, 2: 2, 3: 3});

  // Else if false.
  Expect.identical(map,
      const <int, int>{1: 1, if (false) 9: 9 else 2: 2, 3: 3});

  // Only if.
  Expect.identical(const {1: 1}, const <int, int>{if (true) 1: 1});

  // If at beginning.
  Expect.identical(map, const <int, int>{if (true) 1: 1, 2: 2, 3: 3});

  // If in middle.
  Expect.identical(map, const <int, int>{1: 1, if (true) 2: 2, 3: 3});

  // If at end.
  Expect.identical(map, const <int, int>{1: 1, 2: 2, if (true) 3: 3});

  // Multiple ifs.
  Expect.identical(map,
      const <int, int>{if (true) 1: 1, if (false) 9: 9, 2: 2, if (true) 3: 3});

  // Cast condition.
  Expect.identical(const {1: 1}, const <int, int>{if (dynamicTrue) 1: 1});
  Expect.identical(const {1: 1}, const <int, int>{if (objectTrue) 1: 1});

  // Nested spread.
  Expect.identical(map, const <int, int>{
    if (true) ...<int, int>{1: 1, 2: 2},
    if (false) 9: 9 else ...<int, int>{3: 3}
  });

  // Nested if in then.
  Expect.identical(const {1: 1},
      const <int, int>{if (true) if (true) 1: 1, if (true) if (false) 9: 9});

  // Nested if in else.
  Expect.identical(const {1: 1},
      const <int, int>{if (false) 9: 9 else if (true) 1: 1});
}

void testSet() {
  // Then if true.
  Expect.identical(set, const <int>{1, if (true) 2, 3});

  // Nothing if false and no else.
  Expect.identical(set, const <int>{1, if (false) 9, 2, 3});

  // Else if false.
  Expect.identical(set, const <int>{1, if (false) 9 else 2, 3});

  // Only if.
  Expect.identical(const <int>{1}, const <int>{if (true) 1});

  // If at beginning.
  Expect.identical(set, const <int>{if (true) 1, 2, 3});

  // If in middle.
  Expect.identical(set, const <int>{1, if (true) 2, 3});

  // If at end.
  Expect.identical(set, const <int>{1, 2, if (true) 3});

  // Multiple ifs.
  Expect.identical(set,
      const <int>{if (true) 1, if (false) 9, 2, if (true) 3});

  // Cast condition.
  Expect.identical(const <int>{1}, const <int>{if (dynamicTrue) 1});
  Expect.identical(const <int>{1}, const <int>{if (objectTrue) 1});

  // Does not flatten nested collection literal.
  Expect.identical(const <int>[1], const <List<int>>{if (true) [1]}.first);
  Expect.identical(
      const <int, int>{1: 1}, const <Map<int, int>>{if (true) {1: 1}}.first);
  Expect.identical(const <int>{1}, const <Set<int>>{if (true) {1}}.first);

  // Nested spread.
  Expect.identical(set,
      const <int>{if (true) ...<int>[1, 2], if (false) 9 else ...<int>[3]});

  // Nested if in then.
  Expect.identical(const <int>{1},
      const <int>{if (true) if (true) 1, if (true) if (false) 9});

  // Nested if in else.
  Expect.identical(const <int>{1}, const <int>{if (false) 9 else if (true) 1});
}

void testShortCircuit() {
  // A const expression that throws does not cause a compile error if it occurs
  // inside an unchosen branch of an if.

  // Store null in a dynamically-typed constant to avoid the type error on "+".
  const dynamic nil = null;

  Expect.identical(const <int>[1],
      const <int>[if (true) 1, if (false) nil + 1]);
  Expect.identical(const <int>[1, 2],
      const <int>[if (true) 1 else nil + 1, if (false) nil + 1 else 2]);

  Expect.identical(const <int, int>{1: 1}, const <int, int>{
    if (true) 1: 1,
    if (false) nil + 1: 9,
    if (false) 9: nil + 1
  });
  Expect.identical(const <int, int>{1: 1, 2: 2}, const <int, int>{
    if (true) 1: 1 else nil + 1: 9,
    if (false) 9: nil + 1 else 2: 2
  });

  Expect.identical(const <int>{1},
      const <int>{if (true) 1, if (false) nil + 1});
  Expect.identical(const <int>{1, 2},
      const <int>{if (true) 1 else nil + 1, if (false) nil + 1 else 2});

  // A const expression whose value isn't the right type does not cause a
  // compile error if it occurs inside an unchosen branch.
  const dynamic nonInt = "s";

  Expect.identical(const <int>[1], const <int>[if (true) 1, if (false) nonInt]);
  Expect.identical(const <int>[1, 2],
      const <int>[if (true) 1 else nonInt, if (false) nonInt else 2]);

  Expect.identical(const <int, int>{1: 1}, const <int, int>{
    if (true) 1: 1,
    if (false) nonInt: 9,
    if (false) 9: nonInt
  });
  Expect.identical(const <int, int>{1: 1, 2: 2}, const <int, int>{
    if (true) 1: 1 else nonInt: 9,
    if (false) 9: nonInt else 2: 2
  });

  Expect.identical(const <int>{1}, const <int>{if (true) 1, if (false) nonInt});
  Expect.identical(const <int>{1, 2},
      const <int>{if (true) 1 else nonInt, if (false) nonInt else 2});
}

void testDuplicateKeys() {
  // Duplicate keys from unchosen branches are not an error.
  Expect.mapEquals(map, <int, int>{
    1: 1,
    if (false) 1: 1,
    if (true) 2: 2 else 3: 3,
    3: 3
  });

  Expect.setEquals(set, const <int>{1, if (false) 1, if (true) 2 else 3, 3});
}

void testKeyOrder() {
  // Canonicalization isn't affected by which elements are conditional.
  Expect.identical(map,
      const <int, int>{1: 1, if (true) 2: 2, if (false) 9: 9, 3: 3});
  Expect.identical(map,
      const <int, int>{if (false) 9: 9 else 1: 1, 2: 2, if (true) 3: 3});

  Expect.identical(set, const <int>{1, if (true) 2, if (false) 9, 3});
  Expect.identical(set, const <int>{if (false) 9 else 1, 2, if (true) 3});

  // Ordering does affect canonicalization.
  Expect.notIdentical(map, const <int, int>{1: 1, if (true) 3: 3, 2: 2});
  Expect.notIdentical(set, const <int>{1, if (true) 3, 2});
}
