// Copyright (c) 2021, 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.dexsplitter;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ThrowableConsumer;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.apimodel.ApiModelingTestHelper;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * We need to ensure that we distribute the synthetic items in the features where they where
 * generated.
 */
@RunWith(Parameterized.class)
public class SyntheticDistributionTest extends SplitterTestBase {

  public static final String EXPECTED = StringUtils.lines("42");

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

  private final TestParameters parameters;

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

  @Test
  public void testDistribution() throws Exception {
    assumeTrue(parameters.isDexRuntime());
    ThrowableConsumer<R8TestCompileResult> ensureLambdaNotInBase =
        r8TestCompileResult ->
            r8TestCompileResult.inspect(
                base ->
                    assertFalse(
                        base.allClasses().stream().anyMatch(FoundClassSubject::isSynthetic)),
                feature ->
                    assertTrue(
                        feature.allClasses().stream().anyMatch(FoundClassSubject::isSynthetic)));
    ProcessResult processResult =
        testR8Splitter(
            parameters,
            ImmutableSet.of(BaseSuperClass.class, MyFunction.class),
            ImmutableSet.of(FeatureClass.class),
            FeatureClass.class,
            ensureLambdaNotInBase,
            this::configure);
    assertEquals(0, processResult.exitCode);
    assertEquals(StringUtils.lines("42foobar"), processResult.stdout);
  }

  @Test
  public void testNoMergingAcrossBoundaries() throws Exception {
    R8TestCompileResult compileResult =
        testForR8(parameters.getBackend())
            .addProgramClasses(BaseSuperClass.class, MyFunction.class)
            .addFeatureSplitRuntime()
            .addFeatureSplit(FeatureClass.class)
            .addFeatureSplit(Feature2Class.class)
            .addKeepFeatureMainRules(BaseSuperClass.class, FeatureClass.class, Feature2Class.class)
            .apply(this::configure)
            .compile();

    compileResult
        .runFeature(parameters.getRuntime(), FeatureClass.class, compileResult.getFeature(0))
        .assertSuccessWithOutputLines("42foobar");

    compileResult
        .runFeature(parameters.getRuntime(), Feature2Class.class, compileResult.getFeature(1))
        .assertSuccessWithOutputLines("43barfoo");
  }

  private void configure(R8FullTestBuilder testBuilder) throws NoSuchMethodException {
    testBuilder
        // Link against android.jar that contains ReflectiveOperationException.
        .addLibraryFiles(parameters.getDefaultAndroidJarAbove(AndroidApiLevel.K))
        .addKeepMethodRules(
            Reference.methodFromMethod(
                BaseSuperClass.class.getDeclaredMethod(
                    "keptApplyLambda", MyFunction.class, String.class)))
        .enableInliningAnnotations()
        .addDontObfuscate()
        // BaseDexClassLoader was introduced at api level 14.
        .apply(ApiModelingTestHelper::disableOutliningAndStubbing)
        .setMinApi(parameters.getApiLevel());
  }

  public abstract static class BaseSuperClass implements RunInterface {
    @Override
    public void run() {
      System.out.println(getFromFeature());
    }

    public abstract String getFromFeature();

    public String keptApplyLambda(MyFunction fn, String arg) {
      return fn.apply(arg);
    }
  }

  public interface MyFunction {
    String apply(String s);
  }

  public static class FeatureClass extends BaseSuperClass {
    @NeverInline
    public static String getAString() {
      return System.currentTimeMillis() < 2 ? "Not happening" : "foobar";
    }

    @Override
    public void run() {
      super.run();
    }

    @Override
    public String getFromFeature() {
      String s = getAString();
      return useTheLambda(a -> a.concat(s));
    }

    @NeverInline
    private String useTheLambda(MyFunction f) {
      return keptApplyLambda(f, "42");
    }
  }

  public static class Feature2Class extends BaseSuperClass {
    @NeverInline
    public static String getAString() {
      return System.currentTimeMillis() < 2 ? "Not happening" : "barfoo";
    }

    @Override
    public void run() {
      super.run();
    }

    @Override
    public String getFromFeature() {
      // The lambda is the same as in FeatureClass, but we should not share it since there is
      // no way for Feature2Class to access code in Feature1Class (assuming either that
      // Feature1Class is not installed of isolated splits are used).
      String s = getAString();
      return useTheLambda(a -> a.concat(s));
    }

    @NeverInline
    private String useTheLambda(MyFunction f) {
      return keptApplyLambda(f, "43");
    }
  }
}
