// Copyright (c) 2019, the R8 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.

package com.android.tools.r8.cf;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8CompatTestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class KeepDeserializeLambdaMethodTestRunner extends TestBase {

  private static final Class TEST_CLASS_CF =
      com.android.tools.r8.cf.KeepDeserializeLambdaMethodTestCf.class;
  private static final Class TEST_CLASS_DEX =
      com.android.tools.r8.cf.KeepDeserializeLambdaMethodTestDex.class;

  private static final String EXPECTED =
      StringUtils.lines("base lambda", KeepDeserializeLambdaMethodTest.LAMBDA_MESSAGE);

  @Parameters(name = "{0}")
  public static TestParametersCollection params() {
    return getTestParameters().withAllRuntimesAndApiLevels().build();
  }

  private final TestParameters parameters;

  public KeepDeserializeLambdaMethodTestRunner(TestParameters parameters) {
    this.parameters = parameters;
  }

  private Class<?> getMainClass() {
    return parameters.isCfRuntime() ? TEST_CLASS_CF : TEST_CLASS_DEX;
  }

  private List<Class<?>> getClasses() {
    return ImmutableList.of(KeepDeserializeLambdaMethodTest.class, getMainClass());
  }

  @Test
  public void testReference() throws Exception {
    if (parameters.isCfRuntime()) {
      testForJvm()
          .addProgramClasses(getClasses())
          .run(parameters.getRuntime(), getMainClass())
          .assertSuccessWithOutput(EXPECTED)
          .inspect(this::checkPresenceOfDeserializedLambdas);
    } else {
      testForD8()
          .setMinApi(parameters.getApiLevel())
          .addProgramClasses(getClasses())
          .run(parameters.getRuntime(), getMainClass())
          .assertSuccessWithOutput(EXPECTED)
          .inspect(this::checkPresenceOfDeserializedLambdas);
    }
  }

  @Test
  public void testDontKeepDeserializeLambdaR8() throws Exception {
    test(false);
  }

  @Test
  public void testKeepDeserializedLambdaR8() throws Exception {
    test(true);
  }

  private void test(boolean addKeepDeserializedLambdaRule)
      throws IOException, CompilationFailedException, ExecutionException {
    R8CompatTestBuilder builder =
        testForR8Compat(parameters.getBackend())
            .addProgramClasses(getClasses())
            .setMinApi(parameters.getApiLevel())
            .addKeepMainRule(getMainClass());
    if (addKeepDeserializedLambdaRule) {
      if (parameters.isDexRuntime()) {
        builder.allowUnusedProguardConfigurationRules();
      }
      builder.addKeepRules(
          "-keepclassmembers class * {",
          "private static synthetic java.lang.Object "
              + "$deserializeLambda$(java.lang.invoke.SerializedLambda);",
          "}",
          // TODO(b/148836254): Support deserialized lambdas without the need of additional rules.
          "-keep class * { private static synthetic void lambda$*(); }");
      // TODO(b/148831667): The above rule should pin the names but does not.
      //   Remove the noMinification call once the above rule takes effect.
      builder.noMinification();
    } else {
      builder.noMinification();
      builder.noTreeShaking();
    }
    builder
        .run(parameters.getRuntime(), getMainClass())
        .assertSuccessWithOutput(EXPECTED)
        .inspect(this::checkPresenceOfDeserializedLambdas);
  }

  private void checkPresenceOfDeserializedLambdas(CodeInspector inspector) {
    for (Class<?> clazz : getClasses()) {
      MethodSubject method = inspector.clazz(clazz).uniqueMethodWithName("$deserializeLambda$");
      assertEquals(
          "Unexpected status for $deserializedLambda$ on " + clazz.getSimpleName(),
          parameters.isCfRuntime(),
          method.isPresent());
    }
  }
}
