// 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 '../helpers/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 ? 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});
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler;
    CodegenWorld codegenWorld = compiler.codegenWorldForTesting;

    CallStructure noTypeArguments = new CallStructure(0, [], 0);
    CallStructure oneTypeArgument = new 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]);
  });
}
