// 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.internal.proto;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.graph.DexItemFactory;
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.android.tools.r8.utils.codeinspector.analysis.ProtoApplicationStats;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class Proto2ShrinkingTest extends ProtoShrinkingTestBase {

  private static final String CONTAINS_FLAGGED_OFF_FIELD =
      "com.android.tools.r8.proto2.Shrinking$ContainsFlaggedOffField";
  private static final String EXT_B =
      "com.android.tools.r8.proto2.Shrinking$PartiallyUsedWithExtension$ExtB";
  private static final String EXT_C =
      "com.android.tools.r8.proto2.Shrinking$PartiallyUsedWithExtension$ExtC";
  private static final String FLAGGED_OFF_EXTENSION =
      "com.android.tools.r8.proto2.Shrinking$HasFlaggedOffExtension$Ext";
  private static final String HAS_NO_USED_EXTENSIONS =
      "com.android.tools.r8.proto2.Shrinking$HasNoUsedExtensions";
  private static final String HAS_REQUIRED_FIELD =
      "com.android.tools.r8.proto2.Graph$HasRequiredField";
  private static final String PARTIALLY_USED =
      "com.android.tools.r8.proto2.Shrinking$PartiallyUsed";
  private static final String USED_ROOT = "com.android.tools.r8.proto2.Graph$UsedRoot";
  private static final String USED_VIA_HAZZER =
      "com.android.tools.r8.proto2.Shrinking$UsedViaHazzer";
  private static final String USES_ONLY_REPEATED_FIELDS =
      "com.android.tools.r8.proto2.Shrinking$UsesOnlyRepeatedFields";

  private static List<Path> PROGRAM_FILES =
      ImmutableList.of(PROTO2_EXAMPLES_JAR, PROTO2_PROTO_JAR, PROTOBUF_LITE_JAR);

  private final boolean allowAccessModification;
  private final boolean enableMinification;
  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{2}, allow access modification: {0}, enable minification: {1}")
  public static List<Object[]> data() {
    return buildParameters(
        BooleanUtils.values(),
        BooleanUtils.values(),
        getTestParameters().withAllRuntimes().build());
  }

  public Proto2ShrinkingTest(
      boolean allowAccessModification, boolean enableMinification, TestParameters parameters) {
    this.allowAccessModification = allowAccessModification;
    this.enableMinification = enableMinification;
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    CodeInspector inputInspector = new CodeInspector(PROGRAM_FILES);
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramFiles(PROGRAM_FILES)
            .addKeepMainRule("proto2.TestClass")
            .addKeepRuleFiles(PROTOBUF_LITE_PROGUARD_RULES)
            .addKeepRules(alwaysInlineNewSingularGeneratedExtensionRule())
            // TODO(b/112437944): Attempt to prove that DEFAULT_INSTANCE is non-null, such that the
            //  following "assumenotnull" rule can be omitted.
            .addKeepRules(
                "-assumenosideeffects class " + EXT_C + " {",
                "  private static final " + EXT_C + " DEFAULT_INSTANCE return 1..42;",
                "}")
            .addOptionsModification(
                options -> {
                  options.enableFieldBitAccessAnalysis = true;
                  options.enableGeneratedMessageLiteShrinking = true;
                  options.enableGeneratedExtensionRegistryShrinking = true;
                  options.enableStringSwitchConversion = true;
                })
            .allowAccessModification(allowAccessModification)
            .allowUnusedProguardConfigurationRules()
            .minification(enableMinification)
            .setMinApi(parameters.getRuntime())
            .compile()
            .inspect(
                outputInspector -> {
                  verifyMapAndRequiredFieldsAreKept(inputInspector, outputInspector);
                  verifyUnusedExtensionsAreRemoved(inputInspector, outputInspector);
                  verifyUnusedFieldsAreRemoved(inputInspector, outputInspector);
                  verifyUnusedHazzerBitFieldsAreRemoved(inputInspector, outputInspector);
                  verifyUnusedTypesAreRemoved(inputInspector, outputInspector);
                })
            .run(parameters.getRuntime(), "proto2.TestClass")
            .assertSuccessWithOutputLines(
                "--- roundtrip ---",
                "true",
                "123",
                "asdf",
                "9223372036854775807",
                "qwerty",
                "--- partiallyUsed_proto2 ---",
                "true",
                "42",
                "--- usedViaHazzer ---",
                "true",
                "--- usedViaOneofCase ---",
                "true",
                "--- usesOnlyRepeatedFields ---",
                "1",
                "--- containsFlaggedOffField ---",
                "0",
                "--- hasFlaggedOffExtension ---",
                "4",
                "--- useOneExtension ---",
                "42",
                "--- keepMapAndRequiredFields ---",
                "true",
                "10",
                "10",
                "10");

    if (ToolHelper.isLocalDevelopment()) {
      DexItemFactory dexItemFactory = new DexItemFactory();
      ProtoApplicationStats original = new ProtoApplicationStats(dexItemFactory, inputInspector);
      ProtoApplicationStats actual =
          new ProtoApplicationStats(dexItemFactory, result.inspector(), original);
      System.out.println(actual.getStats());
    }
  }

  private void verifyMapAndRequiredFieldsAreKept(
      CodeInspector inputInspector, CodeInspector outputInspector) {
    // Verify the existence of various fields in the input.
    {
      ClassSubject usedRootClassSubject = inputInspector.clazz(USED_ROOT);
      assertThat(usedRootClassSubject, isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("hasRequiredFieldA_"), isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("hasRequiredFieldB_"), isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("myOneof_"), isPresent());
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("recursiveWithRequiredField_"), isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("isExtendedWithOptional_"), isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("isExtendedWithScalars_"), isPresent());
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("isExtendedWithRequiredField_"), isPresent());
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("isRepeatedlyExtendedWithRequiredField_"),
          isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("hasMapField_"), isPresent());

      ClassSubject hasRequiredFieldClassSubject = inputInspector.clazz(HAS_REQUIRED_FIELD);
      assertThat(hasRequiredFieldClassSubject, isPresent());
      assertThat(hasRequiredFieldClassSubject.uniqueFieldWithName("value_"), isPresent());
    }

    // Verify the existence of various fields in the output.
    {
      ClassSubject usedRootClassSubject = outputInspector.clazz(USED_ROOT);
      assertThat(usedRootClassSubject, isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("hasRequiredFieldA_"), isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("hasRequiredFieldB_"), isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("myOneof_"), isPresent());
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("recursiveWithRequiredField_"), isPresent());
      assertThat(usedRootClassSubject.uniqueFieldWithName("hasMapField_"), isPresent());

      // TODO(b/112437944): Should be present.
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("isExtendedWithRequiredField_"),
          not(isPresent()));
      // TODO(b/112437944): Should be present.
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("isRepeatedlyExtendedWithRequiredField_"),
          not(isPresent()));

      ClassSubject hasRequiredFieldClassSubject = outputInspector.clazz(HAS_REQUIRED_FIELD);
      assertThat(hasRequiredFieldClassSubject, isPresent());
      assertThat(hasRequiredFieldClassSubject.uniqueFieldWithName("value_"), isPresent());
    }

    // Verify the absence of various fields in the output.
    {
      ClassSubject usedRootClassSubject = outputInspector.clazz(USED_ROOT);
      assertThat(usedRootClassSubject, isPresent());
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("isExtendedWithOptional_"), not(isPresent()));
      assertThat(
          usedRootClassSubject.uniqueFieldWithName("isExtendedWithScalars_"), not(isPresent()));
    }
  }

  private void verifyUnusedExtensionsAreRemoved(
      CodeInspector inputInspector, CodeInspector outputInspector) {
    // Verify that the registry was split across multiple methods in the input.
    {
      ClassSubject generatedExtensionRegistryLoader =
          inputInspector.clazz("com.google.protobuf.proto2_registryGeneratedExtensionRegistryLite");
      assertThat(generatedExtensionRegistryLoader, isPresent());
      assertThat(
          generatedExtensionRegistryLoader.uniqueMethodWithName("findLiteExtensionByNumber"),
          isPresent());
      assertThat(
          generatedExtensionRegistryLoader.uniqueMethodWithName("findLiteExtensionByNumber1"),
          isPresent());
      assertThat(
          generatedExtensionRegistryLoader.uniqueMethodWithName("findLiteExtensionByNumber2"),
          isPresent());
    }

    // Verify that the registry methods are still present in the output.
    // TODO(b/112437944): Should they be optimized into a single findLiteExtensionByNumber() method?
    {
      ClassSubject generatedExtensionRegistryLoader =
          outputInspector.clazz(
              "com.google.protobuf.proto2_registryGeneratedExtensionRegistryLite");
      assertThat(generatedExtensionRegistryLoader, isPresent());
      assertThat(
          generatedExtensionRegistryLoader.uniqueMethodWithName("findLiteExtensionByNumber"),
          isPresent());
      assertThat(
          generatedExtensionRegistryLoader.uniqueMethodWithName("findLiteExtensionByNumber1"),
          isPresent());
      assertThat(
          generatedExtensionRegistryLoader.uniqueMethodWithName("findLiteExtensionByNumber2"),
          isPresent());
    }

    // Verify that unused extensions have been removed with -allowaccessmodification.
    if (allowAccessModification) {
      List<String> unusedExtensionNames =
          ImmutableList.of(FLAGGED_OFF_EXTENSION, HAS_NO_USED_EXTENSIONS, EXT_B, EXT_C);
      for (String unusedExtensionName : unusedExtensionNames) {
        assertThat(inputInspector.clazz(unusedExtensionName), isPresent());
        // TODO(b/143588134): Re-enable this assertion.
        // assertThat(outputInspector.clazz(unusedExtensionName), not(isPresent()));
      }
    }
  }

  private void verifyUnusedFieldsAreRemoved(
      CodeInspector inputInspector, CodeInspector outputInspector) {
    // Verify that various proto fields are present the input.
    {
      ClassSubject cfofClassSubject = inputInspector.clazz(CONTAINS_FLAGGED_OFF_FIELD);
      assertThat(cfofClassSubject, isPresent());
      assertThat(cfofClassSubject.uniqueFieldWithName("conditionallyUsed_"), isPresent());

      ClassSubject puClassSubject = inputInspector.clazz(PARTIALLY_USED);
      assertThat(puClassSubject, isPresent());
      assertEquals(7, puClassSubject.allInstanceFields().size());
      assertThat(puClassSubject.uniqueFieldWithName("bitField0_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("used_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("completelyUnused_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("unusedEnum_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("unusedRepeatedEnum_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("unusedMessage_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("unusedRepeatedMessage_"), isPresent());

      ClassSubject uvhClassSubject = inputInspector.clazz(USED_VIA_HAZZER);
      assertThat(uvhClassSubject, isPresent());
      assertThat(uvhClassSubject.uniqueFieldWithName("used_"), isPresent());
      assertThat(uvhClassSubject.uniqueFieldWithName("unused_"), isPresent());
    }

    // Verify that various proto fields have been removed in the output.
    {
      ClassSubject cfofClassSubject = outputInspector.clazz(CONTAINS_FLAGGED_OFF_FIELD);
      assertThat(cfofClassSubject, isPresent());
      assertThat(cfofClassSubject.uniqueFieldWithName("conditionallyUsed_"), not(isPresent()));

      ClassSubject puClassSubject = outputInspector.clazz(PARTIALLY_USED);
      assertThat(puClassSubject, isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("bitField0_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("used_"), isPresent());
      assertThat(puClassSubject.uniqueFieldWithName("completelyUnused_"), not(isPresent()));
      assertThat(puClassSubject.uniqueFieldWithName("unusedEnum_"), not(isPresent()));
      assertThat(puClassSubject.uniqueFieldWithName("unusedRepeatedEnum_"), not(isPresent()));
      assertThat(puClassSubject.uniqueFieldWithName("unusedMessage_"), not(isPresent()));
      assertThat(puClassSubject.uniqueFieldWithName("unusedRepeatedMessage_"), not(isPresent()));

      ClassSubject uvhClassSubject = outputInspector.clazz(USED_VIA_HAZZER);
      assertThat(uvhClassSubject, isPresent());
      assertThat(uvhClassSubject.uniqueFieldWithName("used_"), isPresent());
      assertThat(uvhClassSubject.uniqueFieldWithName("unused_"), not(isPresent()));
    }
  }

  private void verifyUnusedHazzerBitFieldsAreRemoved(
      CodeInspector inputInspector, CodeInspector outputInspector) {
    // Verify that various proto fields are present the input.
    {
      ClassSubject classSubject = inputInspector.clazz(USES_ONLY_REPEATED_FIELDS);
      assertThat(classSubject, isPresent());
      assertThat(classSubject.uniqueFieldWithName("bitField0_"), isPresent());
      assertThat(classSubject.uniqueFieldWithName("myoneof_"), isPresent());
      assertThat(classSubject.uniqueFieldWithName("myoneofCase_"), isPresent());
    }

    // Verify that various proto fields have been removed in the output.
    {
      ClassSubject classSubject = outputInspector.clazz(USES_ONLY_REPEATED_FIELDS);
      assertThat(classSubject, isPresent());
      assertThat(classSubject.uniqueFieldWithName("bitField0_"), not(isPresent()));
      assertThat(classSubject.uniqueFieldWithName("myoneof_"), not(isPresent()));
      assertThat(classSubject.uniqueFieldWithName("myoneofCase_"), not(isPresent()));
    }
  }

  private void verifyUnusedTypesAreRemoved(
      CodeInspector inputInspector, CodeInspector outputInspector) {
    // Verify that various types are present the input.
    {
      ClassSubject enumClassSubject = inputInspector.clazz(PARTIALLY_USED + "$Enum");
      assertThat(enumClassSubject, isPresent());

      ClassSubject nestedClassSubject = inputInspector.clazz(PARTIALLY_USED + "$Nested");
      assertThat(nestedClassSubject, isPresent());
    }

    // Verify that various types have been removed in the output.
    {
      ClassSubject enumClassSubject = outputInspector.clazz(PARTIALLY_USED + "$Enum");
      // TODO(112437944): Should be removed.
      assertThat(enumClassSubject, isPresent());

      ClassSubject nestedClassSubject = outputInspector.clazz(PARTIALLY_USED + "$Nested");
      // TODO(112437944): Should be removed.
      assertThat(nestedClassSubject, isPresent());
    }
  }

  @Test
  public void testNoRewriting() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramFiles(PROGRAM_FILES)
        .addKeepMainRule("proto2.TestClass")
        .addKeepRuleFiles(PROTOBUF_LITE_PROGUARD_RULES)
        // Retain all protos.
        .addKeepRules(keepAllProtosRule())
        // Retain the signature of dynamicMethod() and newMessageInfo().
        .addKeepRules(keepDynamicMethodSignatureRule(), keepNewMessageInfoSignatureRule())
        // Enable the dynamicMethod() rewritings.
        .addOptionsModification(
            options -> {
              assert !options.enableGeneratedMessageLiteShrinking;
              options.enableGeneratedMessageLiteShrinking = true;
            })
        .allowAccessModification(allowAccessModification)
        .allowUnusedProguardConfigurationRules()
        .minification(enableMinification)
        .setMinApi(parameters.getRuntime())
        .compile()
        .inspect(
            inspector ->
                assertRewrittenProtoSchemasMatch(new CodeInspector(PROGRAM_FILES), inspector));
  }
}
