// 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 '../helpers/d8_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'));
    JClosedWorld 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);
  });
}
