// 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: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/elements/names.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/js_model/js_world.dart' show JClosedWorld;
import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';
import '../helpers/d8_helper.dart';
import 'package:compiler/src/util/memory_compiler.dart';

const String SOURCE = r'''
@pragma('dart2js:noInline')
method1<T>(T t) {
  print('method1:');
  print('$t is $T = ${t is T}');
  print('"foo" is $T = ${"foo" is T}');
  print('');
}

@pragma('dart2js: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('');
}

@pragma('dart2js: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) => 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 {
  @pragma('dart2js:tryInline')
  method5<T>(T t) {
    print('Class2.method5:');
    print('$t is $T = ${t is T}');
    print('"foo" is $T = ${"foo" is T}');
    print('');
  }

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

class Class3 {
  @pragma('dart2js: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();
  Class2().method5<int>(0);
  Class3().method6<int>(0);
  dynamic c3 = args != null ? Class3() : Class2();
  c3.method6(0); // Missing type arguments.
  try {
    dynamic c2 = args == null ? Class3() : Class2();
    c2.method6(0); // Valid call.
    c2.method6<int>(0); // Extra type arguments.
  } catch (e) {
    print('noSuchMethod: Class2.method6<int>');
    print('');
  }
  var c = 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 {
    D8Result result = await runWithD8(
      memorySourceFiles: {'main.dart': SOURCE},
      options: [
        Flags.disableRtiOptimization,
        '--libraries-spec=$sdkLibrariesSpecificationUri',
      ],
      expectedOutput: OUTPUT,
      printJs: args.contains('-v'),
    );
    Compiler compiler = result.compilationResult.compiler!;
    JsBackendStrategy backendStrategy = compiler.backendStrategy;
    JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!;
    ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;

    void checkMethod(
      String methodName, {
      String? className,
      required 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!,
                  Name(methodName, cls.library.canonicalUri),
                )
                as FunctionEntity?;
        Expect.isNotNull(method, "Method '$methodName' not found in $cls.");
      } else {
        method =
            elementEnvironment.lookupLibraryMember(
                  elementEnvironment.mainLibrary!,
                  methodName,
                )
                as FunctionEntity?;
        Expect.isNotNull(method, "Method '$methodName' not found.");
      }
      js.Fun fun = backendStrategy.generatedCode[method] as js.Fun;
      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);
  });
}
