// Copyright (c) 2017, 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;

import com.android.tools.r8.code.Const;
import com.android.tools.r8.code.Const16;
import com.android.tools.r8.code.Const4;
import com.android.tools.r8.code.ConstHigh16;
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.ConstStringJumbo;
import com.android.tools.r8.code.ConstWide16;
import com.android.tools.r8.code.ConstWide32;
import com.android.tools.r8.code.FillArrayData;
import com.android.tools.r8.code.FillArrayDataPayload;
import com.android.tools.r8.code.Format35c;
import com.android.tools.r8.code.Format3rc;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.InvokeDirect;
import com.android.tools.r8.code.InvokeDirectRange;
import com.android.tools.r8.code.InvokeInterface;
import com.android.tools.r8.code.InvokeInterfaceRange;
import com.android.tools.r8.code.InvokeStatic;
import com.android.tools.r8.code.InvokeStaticRange;
import com.android.tools.r8.code.InvokeSuper;
import com.android.tools.r8.code.InvokeSuperRange;
import com.android.tools.r8.code.InvokeVirtual;
import com.android.tools.r8.code.InvokeVirtualRange;
import com.android.tools.r8.code.NewArray;
import com.android.tools.r8.code.Sget;
import com.android.tools.r8.code.SgetBoolean;
import com.android.tools.r8.code.SgetByte;
import com.android.tools.r8.code.SgetChar;
import com.android.tools.r8.code.SgetObject;
import com.android.tools.r8.code.SgetShort;
import com.android.tools.r8.code.SgetWide;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.ir.code.SingleConstant;
import com.android.tools.r8.ir.code.WideConstant;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.Streams;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.stream.Stream;

/**
 * This class is deprecated and should not be used. It is a temporary solution to use R8 to analyze
 * dex files and compute resource shrinker related bits.
 *
 * <p>Users or this API should implement {@link ReferenceChecker} interface, and through callbacks
 * in that interface, they will be notified when element relevant for resource shrinking is found.
 *
 * <p>This class extracts all integer constants and string constants, which might refer to resource.
 * More specifically, we look for the following while analyzing dex:
 * <ul>
 *   <li>const instructions that might load integers or strings
 *   <li>static fields that have an initial value. This initial value might be integer, string,
 *   or array of integers.
 *   <li>integer array payloads. Only payloads referenced in fill-array-data instructions will be
 *   processed. More specifically, if a payload is referenced in fill-array-data, and we are able
 *   to determine that array is not array of integers, payload will be ignored. Otherwise, it will
 *   be processed once fill-array-data-payload instruction is encountered.
 *   <li>all annotations (class, field, method) that contain annotation element whose value is
 *   integer, string or array of integers are processed.
 * </ul>
 *
 * <p>Please note that switch payloads are not analyzed. Although they might contain integer
 * constants, ones referring to resource ids would have to be loaded in the code analyzed in list
 * above.
 *
 * <p>Usage of this feature is intentionally not supported from the command line.
 */

// TODO(b/121121779) Remove keep if possible.
@Deprecated
@Keep
final public class ResourceShrinker {

  @Keep
  public final static class Command extends BaseCommand {

    Command(AndroidApp app) {
      super(app);
    }

    @Override
    InternalOptions getInternalOptions() {
      return new InternalOptions();
    }
  }

  @Keep
  public final static class Builder extends BaseCommand.Builder<Command, Builder> {

    @Override
    Builder self() {
      return this;
    }

    @Override
    Command makeCommand() {
      return new Command(getAppBuilder().build());
    }
  }

  /**
   * Classes that would like to process data relevant to resource shrinking should implement this
   * interface.
   */
  @KeepForSubclassing
  public interface ReferenceChecker {

    /**
     * Returns if the class with specified internal name should be processed. Typically,
     * resource type classes like R$drawable, R$styleable etc. should be skipped.
     */
    boolean shouldProcess(String internalName);

    void referencedInt(int value);

    void referencedString(String value);

    void referencedStaticField(String internalName, String fieldName);

    void referencedMethod(String internalName, String methodName, String methodDescriptor);
  }

  private static final class DexClassUsageVisitor {

    private final DexProgramClass classDef;
    private final ReferenceChecker callback;

    DexClassUsageVisitor(DexProgramClass classDef, ReferenceChecker callback) {
      this.classDef = classDef;
      this.callback = callback;
    }

    public void visit() {
      if (!callback.shouldProcess(classDef.type.getInternalName())) {
        return;
      }

      for (DexEncodedField field : classDef.staticFields()) {
        DexValue staticValue = field.getStaticValue();
        if (staticValue != null) {
          processFieldValue(staticValue);
        }
      }

      for (DexEncodedMethod method : classDef.allMethodsSorted()) {
        processMethod(method);
      }

      if (classDef.hasClassOrMemberAnnotations()) {
        processAnnotations(classDef);
      }
    }

    private void processFieldValue(DexValue value) {
      switch (value.getValueKind()) {
        case ARRAY:
          for (DexValue elementValue : value.asDexValueArray().getValues()) {
            if (elementValue.isDexValueInt()) {
              callback.referencedInt(elementValue.asDexValueInt().getValue());
            }
          }
          break;

        case INT:
          callback.referencedInt(value.asDexValueInt().getValue());
          break;

        case STRING:
          callback.referencedString(value.asDexValueString().value.toString());
          break;

        default:
          // Intentionally empty.
      }
    }

    private void processMethod(DexEncodedMethod method) {
      Code implementation = method.getCode();
      if (implementation != null) {

        // Tracks the offsets of integer array payloads.
        final Set<Integer> methodIntArrayPayloadOffsets = Sets.newHashSet();
        // First we collect payloads, and then we process them because payload can be before the
        // fill-array-data instruction referencing it.
        final List<FillArrayDataPayload> payloads = Lists.newArrayList();

        Instruction[] instructions = implementation.asDexCode().instructions;
        int current = 0;
        while (current < instructions.length) {
          Instruction instruction = instructions[current];
          if (isIntConstInstruction(instruction)) {
            processIntConstInstruction(instruction);
          } else if (isStringConstInstruction(instruction)) {
            processStringConstantInstruction(instruction);
          } else if (isGetStatic(instruction)) {
            processGetStatic(instruction);
          } else if (isInvokeInstruction(instruction)) {
            processInvokeInstruction(instruction);
          } else if (isInvokeRangeInstruction(instruction)) {
            processInvokeRangeInstruction(instruction);
          } else if (instruction instanceof FillArrayData) {
            processFillArray(instructions, current, methodIntArrayPayloadOffsets);
          } else if (instruction instanceof FillArrayDataPayload) {
            payloads.add((FillArrayDataPayload) instruction);
          }
          current++;
        }

        for (FillArrayDataPayload payload : payloads) {
          if (isIntArrayPayload(payload, methodIntArrayPayloadOffsets)) {
            processIntArrayPayload(payload);
          }
        }
      }
    }

    private void processAnnotations(DexProgramClass classDef) {
      Stream<DexAnnotation> classAnnotations = classDef.annotations().stream();
      Stream<DexAnnotation> fieldAnnotations =
          Streams.stream(classDef.fields())
              .filter(DexEncodedField::hasAnnotations)
              .flatMap(f -> f.annotations().stream());
      Stream<DexAnnotation> methodAnnotations =
          Streams.stream(classDef.methods())
              .filter(DexEncodedMethod::hasAnyAnnotations)
              .flatMap(m -> m.annotations().stream());

      Streams.concat(classAnnotations, fieldAnnotations, methodAnnotations)
          .forEach(
              annotation -> {
                for (DexAnnotationElement element : annotation.annotation.elements) {
                  DexValue value = element.value;
                  processAnnotationValue(value);
                }
              });
    }

    private void processIntArrayPayload(Instruction instruction) {
      FillArrayDataPayload payload = (FillArrayDataPayload) instruction;

      for (int i = 0; i < payload.data.length / 2; i++) {
        int intValue = payload.data[2 * i + 1] << 16 | payload.data[2 * i];
        callback.referencedInt(intValue);
      }
    }

    private boolean isIntArrayPayload(
        Instruction instruction, Set<Integer> methodIntArrayPayloadOffsets) {
      if (!(instruction instanceof FillArrayDataPayload)) {
        return false;
      }

      FillArrayDataPayload payload = (FillArrayDataPayload) instruction;
      return methodIntArrayPayloadOffsets.contains(payload.getOffset());
    }

    private void processFillArray(
        Instruction[] instructions, int current, Set<Integer> methodIntArrayPayloadOffsets) {
      FillArrayData fillArrayData = (FillArrayData) instructions[current];
      if (current > 0 && instructions[current - 1] instanceof NewArray) {
        NewArray newArray = (NewArray) instructions[current - 1];
        if (!Objects.equals(newArray.getType().descriptor.toString(), "[I")) {
          return;
        }
        // Typically, new-array is right before fill-array-data. If not, assume referenced array is
        // of integers. This can be improved later, but for now we make sure no ints are missed.
      }

      methodIntArrayPayloadOffsets.add(
          fillArrayData.getPayloadOffset() + fillArrayData.getOffset());
    }

    private void processAnnotationValue(DexValue value) {
      switch (value.getValueKind()) {
        case ANNOTATION:
          for (DexAnnotationElement element : value.asDexValueAnnotation().value.elements) {
            processAnnotationValue(element.value);
          }
          break;

        case ARRAY:
          for (DexValue elementValue : value.asDexValueArray().getValues()) {
            processAnnotationValue(elementValue);
          }
          break;

        case INT:
          callback.referencedInt(value.asDexValueInt().value);
          break;

        case STRING:
          callback.referencedString(value.asDexValueString().value.toString());
          break;

        default:
          // Intentionally empty.
      }
    }

    private boolean isIntConstInstruction(Instruction instruction) {
      int opcode = instruction.getOpcode();
      return opcode == Const4.OPCODE
          || opcode == Const16.OPCODE
          || opcode == Const.OPCODE
          || opcode == ConstWide32.OPCODE
          || opcode == ConstHigh16.OPCODE
          || opcode == ConstWide16.OPCODE;
    }

    private void processIntConstInstruction(Instruction instruction) {
      assert isIntConstInstruction(instruction);

      int constantValue;
      if (instruction instanceof SingleConstant) {
        SingleConstant singleConstant = (SingleConstant) instruction;
        constantValue = singleConstant.decodedValue();
      } else if (instruction instanceof WideConstant) {
        WideConstant wideConstant = (WideConstant) instruction;
        if (((int) wideConstant.decodedValue()) != wideConstant.decodedValue()) {
          // We care only about values that fit in int range.
          return;
        }
        constantValue = (int) wideConstant.decodedValue();
      } else {
        throw new AssertionError("Not an int const instruction.");
      }

      callback.referencedInt(constantValue);
    }

    private boolean isStringConstInstruction(Instruction instruction) {
      int opcode = instruction.getOpcode();
      return opcode == ConstString.OPCODE || opcode == ConstStringJumbo.OPCODE;
    }

    private void processStringConstantInstruction(Instruction instruction) {
      assert isStringConstInstruction(instruction);

      String constantValue;
      if (instruction instanceof ConstString) {
        ConstString constString = (ConstString) instruction;
        constantValue = constString.getString().toString();
      } else if (instruction instanceof ConstStringJumbo) {
        ConstStringJumbo constStringJumbo = (ConstStringJumbo) instruction;
        constantValue = constStringJumbo.getString().toString();
      } else {
        throw new AssertionError("Not a string constant instruction.");
      }

      callback.referencedString(constantValue);
    }

    private boolean isGetStatic(Instruction instruction) {
      int opcode = instruction.getOpcode();
      return opcode == Sget.OPCODE
          || opcode == SgetBoolean.OPCODE
          || opcode == SgetByte.OPCODE
          || opcode == SgetChar.OPCODE
          || opcode == SgetObject.OPCODE
          || opcode == SgetShort.OPCODE
          || opcode == SgetWide.OPCODE;
    }

    private void processGetStatic(Instruction instruction) {
      assert isGetStatic(instruction);

      DexField field;
      if (instruction instanceof Sget) {
        Sget sget = (Sget) instruction;
        field = sget.getField();
      } else if (instruction instanceof SgetBoolean) {
        SgetBoolean sgetBoolean = (SgetBoolean) instruction;
        field = sgetBoolean.getField();
      } else if (instruction instanceof SgetByte) {
        SgetByte sgetByte = (SgetByte) instruction;
        field = sgetByte.getField();
      } else if (instruction instanceof SgetChar) {
        SgetChar sgetChar = (SgetChar) instruction;
        field = sgetChar.getField();
      } else if (instruction instanceof SgetObject) {
        SgetObject sgetObject = (SgetObject) instruction;
        field = sgetObject.getField();
      } else if (instruction instanceof SgetShort) {
        SgetShort sgetShort = (SgetShort) instruction;
        field = sgetShort.getField();
      } else if (instruction instanceof SgetWide) {
        SgetWide sgetWide = (SgetWide) instruction;
        field = sgetWide.getField();
      } else {
        throw new AssertionError("Not a get static instruction");
      }

      callback.referencedStaticField(field.holder.getInternalName(), field.name.toString());
    }

    private boolean isInvokeInstruction(Instruction instruction) {
      int opcode = instruction.getOpcode();
      return opcode == InvokeVirtual.OPCODE
          || opcode == InvokeSuper.OPCODE
          || opcode == InvokeDirect.OPCODE
          || opcode == InvokeStatic.OPCODE
          || opcode == InvokeInterface.OPCODE;
    }

    private void processInvokeInstruction(Instruction instruction) {
      assert isInvokeInstruction(instruction);

      Format35c ins35c = (Format35c) instruction;
      DexMethod method = (DexMethod) ins35c.BBBB;

      callback.referencedMethod(
          method.holder.getInternalName(),
          method.name.toString(),
          method.proto.toDescriptorString());
    }

    private boolean isInvokeRangeInstruction(Instruction instruction) {
      int opcode = instruction.getOpcode();
      return opcode == InvokeVirtualRange.OPCODE
          || opcode == InvokeSuperRange.OPCODE
          || opcode == InvokeDirectRange.OPCODE
          || opcode == InvokeStaticRange.OPCODE
          || opcode == InvokeInterfaceRange.OPCODE;
    }

    private void processInvokeRangeInstruction(Instruction instruction) {
      assert isInvokeRangeInstruction(instruction);

      Format3rc ins3rc = (Format3rc) instruction;
      DexMethod method = (DexMethod) ins3rc.BBBB;

      callback.referencedMethod(
          method.holder.getInternalName(),
          method.name.toString(),
          method.proto.toDescriptorString());
    }
  }

  public static void run(Command command, ReferenceChecker callback)
      throws IOException, ExecutionException {
    AndroidApp inputApp = command.getInputApp();
    Timing timing = new Timing("resource shrinker analyzer");
    DexApplication dexApplication =
        new ApplicationReader(inputApp, command.getInternalOptions(), timing).read();
    for (DexProgramClass programClass : dexApplication.classes()) {
      new DexClassUsageVisitor(programClass, callback).visit();
    }
  }
}
