// 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.useKernel,
      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);
  });
}
