// 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/compiler.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/world_builder.dart';
import 'package:expect/expect.dart';

import '../memory_compiler.dart';

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

class Class1 {
  @noInline
  method1<T>() {}

  @noInline
  method2<T>() {}

  @noInline
  method3<T>() {}

  @noInline
  method4<T>() {}

  @noInline
  method5<T>() {}
}

class Class2 {}

class Class3 implements Class1 {
  @noInline
  method1<T>() {}

  @noInline
  method2<T>() {}

  @noInline
  method3<T>() {}

  @noInline
  method4<T>() {}

  @noInline
  method5<T>() {}
}

main(args) {
  dynamic c1 = args != null ? new Class1() : new Class2();
  c1.method1(); // No type arguments are inferred here.

  dynamic c2 = args != null ? new Class1() : new Class2();
  c2.method2<int>();

  var c3 = args != null ? new Class1() : new Class3();
  c3.method3(); // Type arguments are inferred here.

  var c4 = args != null ? new Class1() : new Class3();
  c4.method4<int>();

  dynamic c5 = args != null ? new Class1() : new Class2();
  c5.method5(); // No type arguments are inferred here.

  var c6 = args != null ? new Class1() : new Class3();
  c6.method5();  // Type arguments are inferred here.
}
''';

main() {
  asyncTest(() async {
    CompilationResult result = await runCompiler(
        memorySourceFiles: {'main.dart': code},
        options: [Flags.useKernel, Flags.strongMode]);
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler;
    CodegenWorldBuilder worldBuilder = compiler.codegenWorldBuilder;

    CallStructure noTypeArguments = new CallStructure(0, [], 0);
    CallStructure oneTypeArgument = new CallStructure(0, [], 1);

    Iterable<CallStructure> getCallStructures(String name) {
      return worldBuilder
              .invocationsByName(name)
              ?.keys
              ?.map((s) => s.callStructure) ??
          [];
    }

    void checkInvocationsFor(
        String methodName, List<CallStructure> expectedCallStructures) {
      Iterable<CallStructure> actualCallStructures =
          getCallStructures(methodName);
      Expect.setEquals(
          expectedCallStructures,
          actualCallStructures,
          "Unexpected call structures for '$methodName'. "
          "Expected ${expectedCallStructures}, "
          "actual ${actualCallStructures}.");
    }

    checkInvocationsFor('method1', [noTypeArguments]);
    checkInvocationsFor('method2', [oneTypeArgument]);
    checkInvocationsFor('method3', [oneTypeArgument]);
    checkInvocationsFor('method4', [oneTypeArgument]);
    checkInvocationsFor('method5', [noTypeArguments, oneTypeArgument]);
  });
}
