// 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>() => T;

  @noInline
  method3<T>() => T;

  @noInline
  method4<T>() => T;

  @noInline
  method5<T>() => T;

  @noInline
  method6<T>() {}
}

class Class2 {}

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

  @noInline
  method2<T>() {}

  @noInline
  method3<T>() {}

  @noInline
  method4<T>() {}

  @noInline
  method5<T>() {}

  @noInline
  method6<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.

  dynamic c7 = args != null ? new Class1() : new Class2();
  c7.method6<int>(); // Type arguments are not needed.

  var c8 = args != null ? new Class1() : new Class3();
  c8.method6(); // Type arguments are inferred here but not needed.
}
''';

main() {
  asyncTest(() async {
    CompilationResult result = await runCompiler(
        memorySourceFiles: {'main.dart': code}, options: [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]);
    checkInvocationsFor('method6', [noTypeArguments]);
  });
}
