// Copyright (c) 2017, 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";

typedef String F(String returns, String arguments, [Map<String, String> named]);

/// Formats a type like `(String, [int], {bool name}) => double`.
String fn(String returns, String positional,
    [Map<String, String> named = const {}]) {
  var result = new StringBuffer();
  result.write("($positional");
  if (positional != "" && named.isNotEmpty) result.write(", ");
  if (named.isNotEmpty) {
    result.write("{");
    bool first = true;
    named.forEach((name, type) {
      if (first) {
        first = false;
      } else {
        result.write(", ");
      }
      result.write("$type $name");
    });
    result.write("}");
  }
  result.write(") => $returns");
  return result.toString();
}

main() {
  // Types that do not use class names - these can be checked on dart2js in
  // minified mode.

  check(fn('dynamic', ''), main); //        Top-level tear-off.
  check(fn('void', ''), Xyzzy.foo); //      Class static member tear-off.
  check(fn('void', 'Object'), new MyList().add); //  Instance tear-off.
  check(fn('int', ''), () => 1); //       closure.

  var s = new Xyzzy().runtimeType.toString();
  if (s.length <= 3) return; // dart2js --minify has minified names.

  Expect.equals('Xyzzy', s, 'runtime type of plain class prints as class name');

  check(fn('void', 'String, dynamic'), check);

  // Class static member tear-offs.
  check(fn('String', 'String, [String, dynamic]'), Xyzzy.opt);
  check(fn('String', 'String', {'a': 'String', 'b': 'dynamic'}), Xyzzy.nam);

  // Instance method tear-offs.
  check(fn('void', 'Object'), new MyList<String>().add);
  check(fn('void', 'Object'), new MyList<int>().add);
  check(fn('void', 'int'), new Xyzzy().intAdd);

  check(fn('String', 'Object'), new G<String, int>().foo);

  // Instance method with function parameter.
  var string2int = fn('int', 'String');
  check(fn('String', 'Object'), new G<String, int>().moo);
  check(fn('String', '$string2int'), new G<String, int>().higherOrder);

  // Closures.
  String localFunc(String a, String b, [Map<String, String> named]) => a + b;
  void localFunc2(int a) {
    print(a);
  }

  Expect.isTrue(localFunc is F);
  check(fn('String', 'String, String, [Map<String, String>]'), localFunc);
  check(fn('void', 'int'), localFunc2);
}

void check(String text, var thing) {
  var type = thing.runtimeType.toString();
  if (type == text) return;
  Expect.fail("""
Type print string does not match expectation
  Expected: '$text'
  Actual: '$type'
""");
}

class Xyzzy {
  static void foo() {}
  static String opt(String x, [String a, b]) {}
  static String nam(String x, {String a, b}) {}
  void intAdd(int x) {}
}

// Using 'MyList' instead of core lib 'List' keeps covariant parameter type of
// tear-offs 'Object' (legacy lib) instead of 'Object?' (opted-in lib).
class MyList<E> {
  void add(E value) {}
}

class G<U, V> {
  U foo(V x) => null;
  U moo(V f(U x)) => null;
  U higherOrder(int f(U x)) => null;
}
