// 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:compiler/src/common/elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_backend/runtime_types_resolution.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js_model/js_strategy.dart';
import 'package:compiler/src/js/js.dart' as js;
import 'package:compiler/src/js_model/js_world.dart' show JClosedWorld;
import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';
import '../helpers/program_lookup.dart';
import 'package:compiler/src/util/memory_compiler.dart';

const String code = '''
class A<T> {
  final field;

  @pragma('dart2js:noInline')
  factory A.fact(t) => A(t);

  @pragma('dart2js:noInline')
  A(t) : field = t is T;
}

// A call to A.fact.
@pragma('dart2js:noInline')
callAfact() => A<int>.fact(0).runtimeType;

main() {
  callAfact();
}
''';

main() {
  asyncTest(() async {
    CompilationResult result = await runCompiler(
      memorySourceFiles: {'main.dart': code},
    );
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler!;
    JsBackendStrategy backendStrategy = compiler.backendStrategy;
    JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!;
    RuntimeTypesNeed rtiNeed = closedWorld.rtiNeed;
    ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
    ProgramLookup programLookup = ProgramLookup(backendStrategy);

    js.Name getName(String name) {
      return backendStrategy.namerForTesting.globalPropertyNameForMember(
        lookupMember(elementEnvironment, name),
      );
    }

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

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

      final fun = method.code as js.Fun;
      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.fact',
      expectedParameterCount: 2,
      needsTypeArguments: false,
    );
    checkParameters('A.', expectedParameterCount: 2, needsTypeArguments: false);

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

      final fun = method.code as js.Fun;

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

    // The declarations should have type parameters only when needed by the
    // selector.
    checkArguments('callAfact', 'A.fact', expectedTypeArguments: 2);
  });
}
