// 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.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
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;

// TODO(b/112437944): Strengthen test to ensure that builder inlining succeeds even without single-
//  and double-caller inlining.
@RunWith(Parameterized.class)
public class Proto2BuilderShrinkingTest extends ProtoShrinkingTestBase {

  private static final String METHOD_TO_INVOKE_ENUM =
      "com.google.protobuf.GeneratedMessageLite$MethodToInvoke";

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

  private final List<String> mains;
  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{1}, {0}")
  public static List<Object[]> data() {
    return buildParameters(
        ImmutableList.of(
            ImmutableList.of("proto2.BuilderWithOneofSetterTestClass"),
            ImmutableList.of("proto2.BuilderWithPrimitiveSettersTestClass"),
            ImmutableList.of("proto2.BuilderWithProtoBuilderSetterTestClass"),
            ImmutableList.of("proto2.BuilderWithProtoSetterTestClass"),
            ImmutableList.of("proto2.BuilderWithReusedSettersTestClass"),
            ImmutableList.of("proto2.HasFlaggedOffExtensionBuilderTestClass"),
            ImmutableList.of(
                "proto2.BuilderWithOneofSetterTestClass",
                "proto2.BuilderWithPrimitiveSettersTestClass",
                "proto2.BuilderWithProtoBuilderSetterTestClass",
                "proto2.BuilderWithProtoSetterTestClass",
                "proto2.BuilderWithReusedSettersTestClass",
                "proto2.HasFlaggedOffExtensionBuilderTestClass")),
        getTestParameters().withAllRuntimesAndApiLevels().build());
  }

  public Proto2BuilderShrinkingTest(List<String> mains, TestParameters parameters) {
    this.mains = mains;
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    R8TestCompileResult result =
        testForR8(parameters.getBackend())
            .addProgramFiles(PROGRAM_FILES)
            .addKeepMainRules(mains)
            .addKeepRuleFiles(PROTOBUF_LITE_PROGUARD_RULES)
            .allowAccessModification()
            .allowDiagnosticMessages()
            .allowUnusedDontWarnPatterns()
            .allowUnusedProguardConfigurationRules()
            .enableInliningAnnotations()
            .enableProtoShrinking()
            .setMinApi(parameters.getApiLevel())
            .compile()
            .assertAllInfoMessagesMatch(
                containsString("Proguard configuration rule does not match anything"))
            .assertAllWarningMessagesMatch(
                equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
            .inspect(this::inspect);

    for (String main : mains) {
      result.run(parameters.getRuntime(), main).assertSuccessWithOutput(getExpectedOutput(main));
    }
  }

  private static String getExpectedOutput(String main) {
    switch (main) {
      case "proto2.BuilderWithOneofSetterTestClass":
        return StringUtils.lines(
            "builderWithOneofSetter",
            "false",
            "0",
            "true",
            "foo",
            "false",
            "0",
            "false",
            "0",
            "false",
            "");
      case "proto2.BuilderWithPrimitiveSettersTestClass":
        return StringUtils.lines(
            "builderWithPrimitiveSetters",
            "true",
            "17",
            "false",
            "",
            "false",
            "0",
            "false",
            "0",
            "false",
            "",
            "false",
            "0",
            "false",
            "",
            "false",
            "0",
            "true",
            "16",
            "false",
            "");
      case "proto2.BuilderWithProtoBuilderSetterTestClass":
        return StringUtils.lines("builderWithProtoBuilderSetter", "42");
      case "proto2.BuilderWithProtoSetterTestClass":
        return StringUtils.lines("builderWithProtoSetter", "42");
      case "proto2.BuilderWithReusedSettersTestClass":
        return StringUtils.lines(
            "builderWithReusedSetters",
            "true",
            "1",
            "false",
            "",
            "false",
            "0",
            "false",
            "0",
            "false",
            "",
            "true",
            "1",
            "false",
            "",
            "false",
            "0",
            "false",
            "0",
            "true",
            "qux");
      case "proto2.HasFlaggedOffExtensionBuilderTestClass":
        return StringUtils.lines("4");
      default:
        throw new Unreachable();
    }
  }

  private void inspect(CodeInspector outputInspector) {
    verifyBuildersAreAbsent(outputInspector);
    verifyMethodToInvokeValuesAreAbsent(outputInspector);
  }

  private void verifyBuildersAreAbsent(CodeInspector outputInspector) {
    // TODO(b/171441793): Should be optimized out but fails do to soft pinning of super class.
    if (true) {
      return;
    }
    assertThat(
        outputInspector.clazz(
            "com.android.tools.r8.proto2.Shrinking$HasFlaggedOffExtension$Builder"),
        not(isPresent()));
    assertThat(
        outputInspector.clazz("com.android.tools.r8.proto2.TestProto$Primitives$Builder"),
        not(isPresent()));
    assertThat(
        outputInspector.clazz("com.android.tools.r8.proto2.TestProto$OuterMessage$Builder"),
        not(isPresent()));
    assertThat(
        outputInspector.clazz("com.android.tools.r8.proto2.TestProto$NestedMessage$Builder"),
        not(isPresent()));
  }

  private void verifyMethodToInvokeValuesAreAbsent(CodeInspector outputInspector) {
    DexType methodToInvokeType =
        outputInspector.clazz(METHOD_TO_INVOKE_ENUM).getDexProgramClass().type;
    for (String main : mains) {
      MethodSubject mainMethodSubject = outputInspector.clazz(main).mainMethod();
      assertThat(mainMethodSubject, isPresent());
      assertTrue(
          main,
          mainMethodSubject
              .streamInstructions()
              .filter(InstructionSubject::isStaticGet)
              .map(instruction -> instruction.getField().type)
              .noneMatch(methodToInvokeType::equals));
      assertTrue(mainMethodSubject.streamInstructions().noneMatch(InstructionSubject::isSwitch));
    }
  }
}
