// 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 '../helpers/memory_compiler.dart';

const String code = '''
// This needs one-arg instantiation.
@pragma('dart2js:noInline')
T f1a<T>(T t) => t;

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

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

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

@pragma('dart2js:noInline')
int method1(int i, int Function(int) f) => f(i);

@pragma('dart2js:noInline')
bool method2(int a, int b, bool Function(int, int) f) => f(a, b);

@pragma('dart2js: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.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']);
  });
}
