// Copyright (c) 2020, 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 com.android.tools.r8.shaking.ProguardConfigurationParser.FLATTEN_PACKAGE_HIERARCHY;
import static com.android.tools.r8.shaking.ProguardConfigurationParser.REPACKAGE_CLASSES;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;

import com.android.tools.r8.NeverPropagateValue;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
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;
import org.junit.runners.Parameterized.Parameters;

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

  private final boolean enableMemberValuePropagationAnnotations;

  @Parameters(name = "{2}, kind: {1}, @NeverPropagateValue: {0}")
  public static List<Object[]> data() {
    return buildParameters(
        BooleanUtils.values(),
        ImmutableList.of(FLATTEN_PACKAGE_HIERARCHY, REPACKAGE_CLASSES),
        getTestParameters().withAllRuntimesAndApiLevels().build());
  }

  public RepackageWithInitClassTest(
      boolean enableMemberValuePropagationAnnotations,
      String flattenPackageHierarchyOrRepackageClasses,
      TestParameters parameters) {
    super(flattenPackageHierarchyOrRepackageClasses, parameters);
    this.enableMemberValuePropagationAnnotations = enableMemberValuePropagationAnnotations;
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(getClass())
        .addClassObfuscationDictionary("a")
        .addKeepMainRule(TestClass.class)
        .addMemberValuePropagationAnnotations()
        .apply(this::configureRepackaging)
        .enableMemberValuePropagationAnnotations(enableMemberValuePropagationAnnotations)
        .addOptionsModification(options -> options.enableRedundantFieldLoadElimination = false)
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(this::inspect)
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutputLines("Hello world!");
  }

  private void inspect(CodeInspector inspector) {
    ClassSubject repackagedClassSubject = inspector.clazz(StaticMemberValuePropagation.class);
    assertThat(repackagedClassSubject, isPresent());

    String clinitFieldName = inspector.getFactory().objectMembers.clinitField.name.toSourceString();
    if (enableMemberValuePropagationAnnotations) {
      // No $r8$clinit field should have been synthesized since we can use the HELLO field.
      assertThat(
          repackagedClassSubject.uniqueFieldWithOriginalName(clinitFieldName), not(isPresent()));
      assertThat(repackagedClassSubject.uniqueFieldWithOriginalName("HELLO"), isPresent());

      // Verify that the WORLD field has been removed.
      assertThat(repackagedClassSubject.uniqueFieldWithOriginalName("WORLD"), not(isPresent()));

      // Verify that the class was not repackaged.
      assertThat(StaticMemberValuePropagation.class, isNotRepackaged(inspector));
    } else {
      // Verify that a $r8$clinit field was synthesized.
      assertThat(repackagedClassSubject.uniqueFieldWithOriginalName(clinitFieldName), isPresent());

      // Verify that both fields have been removed.
      assertThat(repackagedClassSubject.uniqueFieldWithOriginalName("HELLO"), not(isPresent()));
      assertThat(repackagedClassSubject.uniqueFieldWithOriginalName("WORLD"), not(isPresent()));

      // Verify that the class was repackaged.
      assertThat(StaticMemberValuePropagation.class, isRepackaged(inspector));
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      System.out.println(StaticMemberValuePropagation.WORLD);
    }
  }

  public static class StaticMemberValuePropagation {

    @NeverPropagateValue static String HELLO = "Hello";

    public static String WORLD = " world!";

    static {
      System.out.print(HELLO);
    }
  }
}
