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

import 'package:compiler/src/util/memory_compiler.dart';

const String code = r'''
class Class1 {
  @pragma('dart2js:noInline')
  method1<T>() {}

  @pragma('dart2js:noInline')
  method2<T>() => T;

  @pragma('dart2js:noInline')
  method3<T>() => T;

  @pragma('dart2js:noInline')
  method4<T>() => T;

  @pragma('dart2js:noInline')
  method5<T>() => T;

  @pragma('dart2js:noInline')
  method6<T>() {}
}

class Class2 {}

class Class3 implements Class1 {
  @pragma('dart2js:noInline')
  method1<T>() {}

  @pragma('dart2js:noInline')
  method2<T>() {}

  @pragma('dart2js:noInline')
  method3<T>() {}

  @pragma('dart2js:noInline')
  method4<T>() {}

  @pragma('dart2js:noInline')
  method5<T>() {}

  @pragma('dart2js:noInline')
  method6<T>() {}
}

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

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

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

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

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

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

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

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

main() {
  asyncTest(() async {
    CompilationResult result =
        await runCompiler(memorySourceFiles: {'main.dart': code});
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler!;
    CodegenWorld codegenWorld = compiler.codegenWorldForTesting!;

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

    Iterable<CallStructure> getCallStructures(String name) {
      return codegenWorld
              .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]);
  });
}
