// 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/elements/entities.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import '../helpers/program_lookup.dart';
import '../memory_compiler.dart';

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

// This needs one-arg instantiation.
@noInline
T f1a<T>(T t) => t;

// This needs no instantiation because it is not closurized.
@noInline
T f1b<T>(T t1, T t2) => t1;

class Class {
  // This needs two-arg instantiation.
  @noInline
  bool f2a<T, S>(T t, S s) => t == s;

  // This needs no instantiation because it is not closurized.
  @noInline
  bool f2b<T, S>(T t, S s1, S s2) => t == s1;
}

@noInline
int method1(int i, int Function(int) f) => f(i);

@noInline
bool method2(int a, int b, bool Function(int, int) f) => f(a, b);

@noInline
int method3(int a, int b, int c, int Function(int, int, int) f) => f(a, b, c);

main() {
  // This needs three-arg instantiation.
  T local1<T, S, U>(T t, S s, U u) => t;

  // This needs no instantiation because but a local function is always
  // closurized so we assume it does.
  T local2<T, S, U>(T t, S s, U u1, U u2) => t;

  print(method1(42, f1a));
  print(f1b(42, 87));

  Class c = new Class();
  print(method2(0, 1, c.f2a));
  print(c.f2b(42, 87, 123));

  print(method3(0, 1, 2, local1));
  print(local2(42, 87, 123, 256));
}
''';

main() {
  asyncTest(() async {
    CompilationResult result = await runCompiler(
        memorySourceFiles: {'main.dart': code},
        options: [Flags.strongMode, Flags.omitImplicitChecks]);
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler;
    JClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
    ProgramLookup programLookup = new ProgramLookup(compiler);

    void checkStubs(ClassEntity element, List<String> expectedStubs) {
      Class cls = programLookup.getClass(element);
      List<String> actualStubs = <String>[];
      if (cls != null) {
        for (StubMethod stub in cls.callStubs) {
          actualStubs.add(stub.name.key);
        }
      }
      Expect.setEquals(
          expectedStubs,
          actualStubs,
          "Unexpected stubs for $element:\n "
          "Expected: $expectedStubs\n Actual: $actualStubs");
    }

    checkStubs(closedWorld.commonElements.getInstantiationClass(1),
        [r'call$1', r'$signature']);
    checkStubs(closedWorld.commonElements.getInstantiationClass(2),
        [r'call$2', r'$signature']);
    checkStubs(closedWorld.commonElements.getInstantiationClass(3),
        [r'call$3', r'call$4', r'$signature']);
  });
}
