// Copyright (c) 2016, 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 'literal_type_literal_test.dart' as prefix;

// TODO(rnystrom): This test has a lot of overlap with some other language
// tests, but those are sort of all over the place so I thought it useful to
// test all of the relevant bits in one place here.

class Foo {
  static var property;
  static method() => "result";
}

class Box<T> {
  Type get typeArg => T;
}

class G<A, B> {}

/// A typedef that defines a non-generic function type.
typedef int Func(bool b);

/// Semantically identical to [Func], but using the Dart 2 syntax.
typedef Func2 = int Function(bool);

/// A typedef that defines a generic function type.
typedef GenericFunc = int Function<T>(T);

/// A typedef with a type parameter that defines a non-generic function type.
typedef int GenericTypedef<T>(T t);

/// Semantically identical to [GenericTypedef], but using the Dart 2 syntax.
typedef GenericTypedef2<T> = int Function(T);

/// A typedef with a type parameter that defines a generic function type.
typedef GenericTypedefAndFunc<S> = S Function<T>(T);

main() {
  // Primitive types.
  testType(Object, "Object");
  testType(Null, "Null");
  testType(bool, "bool");
  testType(double, "double");
  testType(int, "int");
  testType(num, "num");
  testType(String, "String");

  // Class types.
  testType(Foo, "Foo");

  // Generic classes.
  testType(Box, ["Box", "Box<dynamic>"]);
  testType(new Box<Foo>().typeArg, "Foo");
  testType(new Box<dynamic>().typeArg, "dynamic");
  testType(new Box<Box<Foo>>().typeArg, "Box<Foo>");
  testType(G, ["G", "G<dynamic, dynamic>"]);
  testType(new Box<G<int, String>>().typeArg, "G<int, String>");

  // Typedef.
  testType(Func, ["Func", "(bool) => int"]);
  testType(Func2, ["Func2", "(bool) => int"]);
  testType(GenericTypedef,
      ["GenericTypedef", "GenericTypedef<dynamic>", "(dynamic) => int"]);
  testType(GenericTypedef2,
      ["GenericTypedef2", "GenericTypedef2<dynamic>", "(dynamic) => int"]);
  testType(new Box<GenericTypedef<int>>().typeArg,
      ["GenericTypedef<int>", "(int) => int"]);
  testType(GenericFunc, ["GenericFunc", RegExp(r'<(\w+)>\((\1)\) => int')]);
  testType(GenericTypedefAndFunc, [
    "GenericTypedefAndFunc",
    "GenericTypedefAndFunc<dynamic>",
    RegExp(r'<(\w+)>\((\1)\) => dynamic')
  ]);

  // Literals are canonicalized.
  // See type_literal_canonicalization_test.dart

  // Static member uses are not type literals.
  Foo.property = "value";
  Expect.equals("value", Foo.property);
  Expect.equals("result", Foo.method());

  // Prefixed types are type literals.
  testType(prefix.Foo, "Foo");

  // Prefix member uses are not.
  prefix.Foo.property = "value2";
  Expect.equals("value2", prefix.Foo.property);
  Expect.equals("result", prefix.Foo.method());
}

void testType(Type type, Object expectedToStringValues) {
  Expect.isTrue(type is Type);
  String text = type.toString();

  // dart2js minified names should be tagged. We can still test types that don't
  // contain minified names.
  if (text.contains('minified:')) return;

  if (expectedToStringValues is List) {
    var matched = false;
    for (var value in expectedToStringValues) {
      if (value is String) {
        matched = matched || value == text;
      } else if (value is RegExp) {
        matched = matched || value.hasMatch(text);
      }
    }
    Expect.isTrue(matched,
        'type `$type`.toString() should be one of: $expectedToStringValues.');
  } else {
    var string = expectedToStringValues as String;
    Expect.equals(string, text);
  }
}
