// 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.ir.analysis.proto.ProtoUtils.getInfoValueFromMessageInfoConstructionInvoke;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.ir.analysis.proto.GeneratedMessageLiteShrinker;
import com.android.tools.r8.ir.analysis.proto.ProtoReferences;
import com.android.tools.r8.ir.analysis.proto.RawMessageInfoDecoder;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public abstract class ProtoShrinkingTestBase extends TestBase {

  public static final Path PROTOBUF_LITE_JAR =
      Paths.get("third_party/protobuf-lite/libprotobuf_lite.jar");

  public static final Path PROTOBUF_LITE_PROGUARD_RULES =
      Paths.get("third_party/protobuf-lite/lite_proguard.pgcfg");

  // Test classes for proto2.
  public static final Path PROTO2_EXAMPLES_JAR =
      Paths.get(ToolHelper.EXAMPLES_PROTO_BUILD_DIR).resolve("proto2.jar");

  // Proto definitions used by test classes for proto2.
  public static final Path PROTO2_PROTO_JAR =
      Paths.get(ToolHelper.GENERATED_PROTO_BUILD_DIR).resolve("proto2.jar");

  // Test classes for proto3.
  public static final Path PROTO3_EXAMPLES_JAR =
      Paths.get(ToolHelper.EXAMPLES_PROTO_BUILD_DIR).resolve("proto3.jar");

  // Proto definitions used by test classes for proto3.
  public static final Path PROTO3_PROTO_JAR =
      Paths.get(ToolHelper.GENERATED_PROTO_BUILD_DIR).resolve("proto3.jar");

  static void assertRewrittenProtoSchemasMatch(
      CodeInspector expectedInspector, CodeInspector actualInspector) throws Exception {
    Map<String, IntList> actualInfos = getInfoValues(actualInspector);

    // Ensure that this cannot fail silently.
    assertTrue(actualInfos.size() > 0);

    Map<String, IntList> expectedInfos = getInfoValues(expectedInspector);
    for (Map.Entry<String, IntList> entry : actualInfos.entrySet()) {
      String className = entry.getKey();
      IntList actualInfo = entry.getValue();
      IntList expectedInfo = expectedInfos.get(className);
      assertNotNull("Expected info value missing for class `" + className + "`", expectedInfo);
      assertEquals("Unexpected info value for class `" + className + "`", expectedInfo, actualInfo);
    }
  }

  static String allGeneratedMessageLiteSubtypesAreInstantiatedRule() {
    return StringUtils.lines(
        "-if class * extends com.google.protobuf.GeneratedMessageLite",
        "-keep,allowobfuscation class <1> {",
        "  <init>(...);",
        "}");
  }

  static String alwaysInlineNewSingularGeneratedExtensionRule() {
    return StringUtils.lines(
        "-alwaysinline class com.google.protobuf.GeneratedMessageLite {",
        "  com.google.protobuf.GeneratedMessageLite$GeneratedExtension"
            + " newSingularGeneratedExtension(...);",
        "}");
  }

  static String keepAllProtosRule() {
    return StringUtils.lines(
        "-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }");
  }

  static String keepDynamicMethodSignatureRule() {
    return StringUtils.lines(
        "-keepclassmembers,includedescriptorclasses class com.google.protobuf.GeneratedMessageLite "
            + "{",
        "  java.lang.Object dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke,"
            + " java.lang.Object, java.lang.Object);",
        "}");
  }

  static String keepNewMessageInfoSignatureRule() {
    return StringUtils.lines(
        "-keepclassmembers,includedescriptorclasses class com.google.protobuf.GeneratedMessageLite "
            + "{",
        "  java.lang.Object newMessageInfo(com.google.protobuf.MessageLite,"
            + " java.lang.String, java.lang.Object[]);",
        "}");
  }

  /**
   * Finds all proto messages and creates a mapping from the type name of the message to the
   * expected info value of the message.
   */
  static Map<String, IntList> getInfoValues(CodeInspector inspector) throws Exception {
    Map<String, IntList> result = new HashMap<>();
    DexItemFactory dexItemFactory = inspector.getFactory();
    ProtoReferences references = new ProtoReferences(dexItemFactory);
    for (FoundClassSubject classSubject : inspector.allClasses()) {
      for (FoundMethodSubject methodSubject : classSubject.virtualMethods()) {
        if (!methodSubject.hasCode() || !references.isDynamicMethod(methodSubject.getMethod())) {
          continue;
        }

        IRCode code = methodSubject.buildIR(dexItemFactory);
        InvokeMethod invoke =
            GeneratedMessageLiteShrinker.getNewMessageInfoInvoke(code, references);
        assert invoke != null;

        IntList info = new IntArrayList();
        RawMessageInfoDecoder.createInfoIterator(
                getInfoValueFromMessageInfoConstructionInvoke(invoke, references))
            .forEachRemaining(info::add);
        result.put(classSubject.getOriginalName(), info);
      }
    }
    return result;
  }
}
