// 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.repackage;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class RepackageFeatureWithSyntheticsTest extends RepackageTestBase {

  public RepackageFeatureWithSyntheticsTest(
      String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
    super(flattenPackageHierarchyOrRepackageClasses, parameters);
  }

  private static final Class<?> FIRST_FOO =
      com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first.Foo.class;

  private static final Class<?> FIRST_PKG_PRIVATE =
      com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first
          .PkgProtectedMethod.class;

  private static final List<Class<?>> FIRST_CLASSES =
      ImmutableList.of(FIRST_FOO, FIRST_PKG_PRIVATE);

  private static final List<Class<?>> FIRST_FIRST_CLASSES =
      ImmutableList.of(
          com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first.first.Foo
              .class,
          com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first.first
              .PkgProtectedMethod.class);

  private static List<Class<?>> getTestClasses() {
    return ImmutableList.<Class<?>>builder()
        .addAll(getBaseClasses())
        .add(TestClass.class)
        .add(I.class)
        .build();
  }

  private static List<Class<?>> getBaseClasses() {
    return FIRST_CLASSES;
  }

  private static List<Class<?>> getFeatureClasses() {
    return FIRST_FIRST_CLASSES;
  }

  private static String EXPECTED = StringUtils.lines("first.Foo", "first.first.Foo");

  @Override
  public String getRepackagePackage() {
    return "dest";
  }

  @Test
  public void testReference() throws Exception {
    testForRuntime(parameters)
        .addProgramClasses(getTestClasses())
        .addProgramClasses(getFeatureClasses())
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(EXPECTED);
  }

  @Test
  public void test() throws Exception {
    assumeTrue("Feature splits require DEX output.", parameters.isDexRuntime());
    R8TestCompileResult compileResult =
        testForR8(parameters.getBackend())
            .addProgramClasses(getTestClasses())
            .addFeatureSplit(getFeatureClasses().toArray(new Class<?>[0]))
            .addKeepMainRule(TestClass.class)
            .addKeepClassAndMembersRules(
                com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first
                    .PkgProtectedMethod.class,
                com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first
                    .first.PkgProtectedMethod.class)
            .addKeepClassAndMembersRules(I.class)
            .addKeepMethodRules(
                Reference.methodFromMethod(TestClass.class.getDeclaredMethod("run", I.class)))
            .addKeepAttributeInnerClassesAndEnclosingMethod()
            .noMinification()
            .apply(this::configureRepackaging)
            .enableNeverClassInliningAnnotations()
            .setMinApi(parameters.getApiLevel())
            .compile();

    // Each Foo class will give rise to a single lambda.
    int expectedSyntheticsInBase = 1;
    int expectedSyntheticsInFeature = 1;

    // Check that the first.Foo is repackaged but that the pkg private access class is not.
    // The implies that the lambda which is doing a package private access cannot be repackaged.
    // If it is, the access will fail resulting in a runtime exception.
    CodeInspector baseInspector = compileResult.inspector();
    assertThat(FIRST_FOO, isRepackagedAsExpected(baseInspector, "first"));
    assertThat(FIRST_PKG_PRIVATE, isNotRepackaged(baseInspector));
    assertEquals(
        getTestClasses().size() + expectedSyntheticsInBase, baseInspector.allClasses().size());

    // The feature first.first.Foo is not repackaged and neither is the lambda.
    // TODO(b/180086194): first.first.Foo should have been repackaged, but is currently identified
    //   as being in 'base' when inlining takes place.
    CodeInspector featureInspector = new CodeInspector(compileResult.getFeature(0));
    getFeatureClasses().forEach(c -> assertThat(c, isNotRepackaged(featureInspector)));
    assertEquals(
        getFeatureClasses().size() + expectedSyntheticsInFeature,
        featureInspector.allClasses().size());

    compileResult
        .addFeatureSplitsToRunClasspathFiles()
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("first.Foo", "first.first.Foo");
  }

  public interface I {
    void run();
  }

  public static class TestClass {

    // Public kept run method to accept a lambda ensuring desugaring which cannot be optimized out.
    public static void run(I i) {
      i.run();
    }

    public static void main(String[] args) {
      new com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first.Foo();
      new com.android.tools.r8.repackage.testclasses.repackagefeaturewithsynthetics.first.first
          .Foo();
    }
  }
}
