// 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.references.Reference;
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
        .addKeepMethodRules(
            Reference.methodFromMethod(
                BaseSuperClass.class.getDeclaredMethod(
                    "keptApplyLambda", MyFunction.class, String.class)))
        .enableInliningAnnotations()
        .noMinification()
        .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");
    }
  }
}
