// Copyright (c) 2018, 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/elements/names.dart';
import 'package:compiler/src/js_backend/runtime_types.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/world.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/selector.dart';
import 'package:expect/expect.dart';
import '../helpers/program_lookup.dart';
import '../memory_compiler.dart';

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

class A {
  // Both method1 implementations need type arguments.
  @noInline
  method1<T>(T t) => t is T;

  // One of the method2 implementations need type arguments.
  @noInline
  method2<T>(T t) => t is T;

  // None of the method3 implementations need type arguments.
  @noInline
  method3<T>(T t) => false;
}

class B {
  @noInline
  method1<T>(T t) => t is T;
  @noInline
  method2<T>(T t) => true;
  @noInline
  method3<T>(T t) => true;
}

// A call to either A.method1 or B.method1.
@noInline
call1(c) => c.method1<int>(0);

// A call to A.method1.
@noInline
call1a() => new A().method1<int>(0);

// A call to B.method1.
@noInline
call1b() => new B().method1<int>(0);

// A call to either A.method2 or B.method2.
@noInline
call2(c) => c.method2<int>(0);

// A call to A.method2.
@noInline
call2a() => new A().method2<int>(0);

// A call to B.method2.
@noInline
call2b() => new B().method2<int>(0);

// A call to either A.method3 or B.method3.
@noInline
call3(c) => c.method3<int>(0);

// A call to A.method3.
@noInline
call3a() => new A().method3<int>(0);

// A call to B.method3.
@noInline
call3b() => new B().method3<int>(0);

main() {
  call1(new A());
  call1(new B());
  call1a();
  call1b();
  call2(new A());
  call2(new B());
  call2a();
  call2b();
  call3(new A());
  call3(new B());
  call3a();
  call3b();
}
''';

main() {
  asyncTest(() async {
    CompilationResult result = await runCompiler(
        memorySourceFiles: {'main.dart': code},
        options: [Flags.strongMode, Flags.useKernel]);
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler;
    ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
    RuntimeTypesNeed rtiNeed = closedWorld.rtiNeed;
    ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
    ProgramLookup programLookup = new ProgramLookup(compiler);

    js.Name getName(String name, int typeArguments) {
      return compiler.backend.namer.invocationName(new Selector.call(
          new PublicName(name),
          new CallStructure(1, const <String>[], typeArguments)));
    }

    void checkParameters(String name,
        {int expectedParameterCount, bool needsTypeArguments}) {
      FunctionEntity function = lookupMember(elementEnvironment, name);

      Expect.equals(
          needsTypeArguments,
          rtiNeed.methodNeedsTypeArguments(function),
          "Unexpected type argument need for $function.");
      Method method = programLookup.getMethod(function);

      js.Fun fun = method.code;
      Expect.equals(expectedParameterCount, fun.params.length,
          "Unexpected parameter count on $function: ${js.nodeToString(fun)}");
    }

    // The declarations should have type parameters only when needed.
    checkParameters('A.method1',
        expectedParameterCount: 2, needsTypeArguments: true);
    checkParameters('B.method1',
        expectedParameterCount: 2, needsTypeArguments: true);
    checkParameters('A.method2',
        expectedParameterCount: 2, needsTypeArguments: true);
    checkParameters('B.method2',
        expectedParameterCount: 1, needsTypeArguments: false);
    checkParameters('A.method3',
        expectedParameterCount: 1, needsTypeArguments: false);
    checkParameters('B.method3',
        expectedParameterCount: 1, needsTypeArguments: false);

    checkArguments(String name, String targetName,
        {int expectedTypeArguments}) {
      FunctionEntity function = lookupMember(elementEnvironment, name);
      Method method = programLookup.getMethod(function);

      js.Fun fun = method.code;

      js.Name selector = getName(targetName, expectedTypeArguments);
      bool callFound = false;
      forEachCall(fun, (js.Call node) {
        js.Expression target = node.target;
        if (target is js.PropertyAccess && target.selector == selector) {
          callFound = true;
          Expect.equals(
              1 + expectedTypeArguments,
              node.arguments.length,
              "Unexpected argument count in $function call to $targetName: "
              "${js.nodeToString(fun)}");
        }
      });
      Expect.isTrue(callFound,
          "No call to $targetName as '${selector.key}' in $function found.");
    }

    // The declarations should have type parameters only when needed by the
    // selector.
    checkArguments('call1', 'method1', expectedTypeArguments: 1);
    checkArguments('call1a', 'method1', expectedTypeArguments: 1);
    checkArguments('call1b', 'method1', expectedTypeArguments: 1);
    checkArguments('call2', 'method2', expectedTypeArguments: 1);
    checkArguments('call2a', 'method2', expectedTypeArguments: 1);
    checkArguments('call2b', 'method2', expectedTypeArguments: 1);
    checkArguments('call3', 'method3', expectedTypeArguments: 0);
    checkArguments('call3a', 'method3', expectedTypeArguments: 0);
    checkArguments('call3b', 'method3', expectedTypeArguments: 0);
  });
}
