// 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.

import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import '../kernel/compiler_helper.dart';

const String SOURCE = r'''
import 'package:meta/dart2js.dart';

@noInline
method1<T>(T t) {
  print('method1:');
  print('$t is $T = ${t is T}');
  print('"foo" is $T = ${"foo" is T}');
  print('');
}

@noInline
method2<T, S>(S s, T t) {
  print('method2:');
  print('$t is $T = ${t is T}');
  print('$s is $T = ${s is T}');
  print('$t is $S = ${t is S}');
  print('$s is $S = ${s is S}');
  print('');
}

@tryInline
method3<T, S>(T t, S s) {
  print('method3:');
  print('$t is $T = ${t is T}');
  print('$s is $T = ${s is T}');
  print('$t is $S = ${t is S}');
  print('$s is $S = ${s is S}');
  print('');
}

class Class1<T> {
  final int index;

  Class1(this.index);

  String toString() => 'c$index';
}

method4<T>(int index) => new Class1<T>(index);

testMethod4() {
  print('method4:');
  var c1 = method4<int>(1);
  var c2 = method4<String>(2);
  print('$c1 is Class1<int> = ${c1 is Class1<int>}');
  print('$c2 is Class1<int> = ${c2 is Class1<int>}');
  print('$c1 is Class1<String> = ${c1 is Class1<String>}');
  print('$c2 is Class1<String> = ${c2 is Class1<String>}');
  print('');
}

class Class2 {
  @tryInline
  method5<T>(T t) {
    print('Class2.method5:');
    print('$t is $T = ${t is T}');
    print('"foo" is $T = ${"foo" is T}');
    print('');
  }

  @noInline
  method6(o) {
    print('Class2.method6:');
    print('$o is int = ${o is int}');
    print('$o is String = ${o is String}');
    print('');
  }
}

class Class3 {
  @noInline
  method6<T>(T t) {
    print('Class3.method6:');
    print('$t is $T = ${t is T}');
    print('"foo" is $T = ${"foo" is T}');
    print('');
  }
}

class Class4<T> {
  Function method7<Q>() {
    foo(T t, Q q) => '';
    return foo;
  }
}

// Nested generic local function.
outside<T>() {
  nested<T>(T t) => '';
  return nested;
}

main(args) {
  method1<int>(0);
  method2<String, double>(0.5, 'foo');
  method3<double, String>(1.5, 'bar');
  testMethod4();
  new Class2().method5<int>(0);
  new Class3().method6<int>(0);
  dynamic c3 = args != null ? new Class3() : new Class2();
  // TODO(johnniwinther): Expected bounds should be `dynamic` when CFE supports
  // instantiate-to-bound.
  c3.method6(0); // Missing type arguments.
  try {
    dynamic c2 = args == null ? new Class3() : new Class2();
    c2.method6(0); // Valid call.
    c2.method6<int>(0); // Extra type arguments.
  } catch (e) {
    print('noSuchMethod: Class2.method6<int>');
    print('');
  }
  var c = new Class4<bool>();
  print((c.method7<int>()).runtimeType);
  outside();
}
''';

const String OUTPUT = r'''
method1:
0 is int = true
"foo" is int = false

method2:
foo is String = true
0.5 is String = false
foo is double = false
0.5 is double = true

method3:
1.5 is double = true
bar is double = false
1.5 is String = false
bar is String = true

method4:
c1 is Class1<int> = true
c2 is Class1<int> = false
c1 is Class1<String> = false
c2 is Class1<String> = true

Class2.method5:
0 is int = true
"foo" is int = false

Class3.method6:
0 is int = true
"foo" is int = false

Class3.method6:
0 is Object = true
"foo" is Object = true

Class2.method6:
0 is int = true
0 is String = false

noSuchMethod: Class2.method6<int>

(bool, int) => String
''';

main(List<String> args) {
  asyncTest(() async {
    Compiler compiler = await runWithD8(memorySourceFiles: {
      'main.dart': SOURCE
    }, options: [
      Flags.strongMode,
      Flags.disableRtiOptimization,
    ], expectedOutput: OUTPUT, printJs: args.contains('-v'));
    ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
    ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;

    void checkMethod(String methodName,
        {String className, int expectedParameterCount}) {
      FunctionEntity method;
      if (className != null) {
        ClassEntity cls = elementEnvironment.lookupClass(
            elementEnvironment.mainLibrary, className);
        Expect.isNotNull(cls, "Class '$className' not found.");
        method = elementEnvironment.lookupClassMember(cls, methodName);
        Expect.isNotNull(method, "Method '$methodName' not found in $cls.");
      } else {
        method = elementEnvironment.lookupLibraryMember(
            elementEnvironment.mainLibrary, methodName);
        Expect.isNotNull(method, "Method '$methodName' not found.");
      }
      js.Fun fun = compiler.backend.generatedCode[method];
      Expect.equals(expectedParameterCount, fun.params.length,
          "Unexpected parameter count for $method:\n${js.nodeToString(fun)}");
    }

    checkMethod('method1', expectedParameterCount: 2);
    checkMethod('method2', expectedParameterCount: 4);
    checkMethod('method6', className: 'Class2', expectedParameterCount: 1);
    checkMethod('method6', className: 'Class3', expectedParameterCount: 2);
  });
}
