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