// 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();
  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 dynamic = true
"foo" is dynamic = 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);
  });
}
