// Copyright (c) 2016, 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.graph;

import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
import com.android.tools.r8.androidapi.ComputedApiLevel;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueByte;
import com.android.tools.r8.graph.DexValue.DexValueInt;
import com.android.tools.r8.graph.DexValue.DexValueMethod;
import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.DexValue.DexValueType;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.ir.desugar.CovariantReturnTypeAnnotationTransformer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.synthesis.SyntheticItems;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.structural.StructuralItem;
import com.android.tools.r8.utils.structural.StructuralMapping;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

public class DexAnnotation extends DexItem implements StructuralItem<DexAnnotation> {

  public enum AnnotatedKind {
    FIELD,
    METHOD,
    TYPE,
    PARAMETER;

    public static AnnotatedKind from(DexDefinition definition) {
      return from(definition.getReference());
    }

    public static AnnotatedKind from(ProgramDefinition definition) {
      return from(definition.getReference());
    }

    public static AnnotatedKind from(DexReference reference) {
      return reference.apply(type -> TYPE, field -> FIELD, method -> METHOD);
    }

    public boolean isParameter() {
      return this == PARAMETER;
    }
  }

  public static final DexAnnotation[] EMPTY_ARRAY = {};
  public static final int VISIBILITY_BUILD = 0x00;
  public static final int VISIBILITY_RUNTIME = 0x01;
  public static final int VISIBILITY_SYSTEM = 0x02;
  public final int visibility;
  public final DexEncodedAnnotation annotation;

  private static final int UNKNOWN_API_LEVEL = -1;
  private static final int NOT_SET_API_LEVEL = -2;

  protected static void specify(StructuralSpecification<DexAnnotation, ?> spec) {
    spec.withItem(a -> a.annotation).withInt(a -> a.visibility);
  }

  public DexAnnotation(int visibility, DexEncodedAnnotation annotation) {
    this.visibility = visibility;
    this.annotation = annotation;
  }

  public boolean isTypeAnnotation() {
    return false;
  }

  public DexTypeAnnotation asTypeAnnotation() {
    return null;
  }

  @Override
  public DexAnnotation self() {
    return this;
  }

  @Override
  public StructuralMapping<DexAnnotation> getStructuralMapping() {
    return DexAnnotation::specify;
  }

  public DexType getAnnotationType() {
    return annotation.type;
  }

  @Override
  public int hashCode() {
    return visibility + annotation.hashCode() * 3;
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (other instanceof DexAnnotation) {
      DexAnnotation o = (DexAnnotation) other;
      return (visibility == o.visibility) && annotation.equals(o.annotation);
    }
    return false;
  }

  @Override
  public String toString() {
    return visibility + " " + annotation;
  }

  public int getVisibility() {
    return visibility;
  }

  public void collectIndexedItems(AppView<?> appView, IndexedItemCollection indexedItems) {
    annotation.collectIndexedItems(appView, indexedItems);
  }

  @Override
  protected void collectMixedSectionItems(MixedSectionCollection mixedItems) {
    mixedItems.add(this);
  }

  public static boolean retainCompileTimeAnnotation(DexType annotation, InternalOptions options) {
    if (options.retainCompileTimeAnnotations) {
      return true;
    }
    if (annotation == options.itemFactory.annotationSynthesizedClass
        || annotation
            .getDescriptor()
            .startsWith(options.itemFactory.dalvikAnnotationOptimizationPrefix)) {
      return true;
    }
    if (options.processCovariantReturnTypeAnnotations) {
      // @CovariantReturnType annotations are processed by CovariantReturnTypeAnnotationTransformer,
      // they thus need to be read here and will then be removed as part of the processing.
      return CovariantReturnTypeAnnotationTransformer.isCovariantReturnTypeAnnotation(
          annotation, options.itemFactory);
    }
    return false;
  }

  public static DexAnnotation createEnclosingClassAnnotation(DexType enclosingClass,
      DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationEnclosingClass, factory,
        new DexValueType(enclosingClass));
  }

  public static DexType getEnclosingClassFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationEnclosingClass, annotation);
    if (value == null) {
      return null;
    }
    return value.asDexValueType().value;
  }

  public static DexAnnotation createEnclosingMethodAnnotation(DexMethod enclosingMethod,
      DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationEnclosingMethod, factory,
        new DexValueMethod(enclosingMethod));
  }

  public static DexMethod getEnclosingMethodFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationEnclosingMethod, annotation);
    if (value == null) {
      return null;
    }
    return value.asDexValueMethod().value;
  }

  public static boolean isEnclosingClassAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationEnclosingClass;
  }

  public static boolean isEnclosingMethodAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationEnclosingMethod;
  }

  public static boolean isInnerClassAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationInnerClass;
  }

  public static boolean isMemberClassesAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationMemberClasses;
  }

  public static boolean isNestHostAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationNestHost;
  }

  public static boolean isNestMembersAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationNestMembers;
  }

  public static boolean isPermittedSubclassesAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationPermittedSubclasses;
  }

  public static boolean isRecordAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.getAnnotationType() == factory.annotationRecord;
  }

  public static DexAnnotation createInnerClassAnnotation(
      DexString clazz, int access, DexItemFactory factory) {
    return new DexAnnotation(
        VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(
            factory.annotationInnerClass,
            new DexAnnotationElement[] {
              new DexAnnotationElement(
                  factory.createString("accessFlags"), DexValueInt.create(access)),
              new DexAnnotationElement(
                  factory.createString("name"),
                  (clazz == null) ? DexValueNull.NULL : new DexValueString(clazz))
            }));
  }

  public static Pair<DexString, Integer> getInnerClassFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    assert isInnerClassAnnotation(annotation, factory);
    DexAnnotationElement[] elements = annotation.annotation.elements;
    Pair<DexString, Integer> result = new Pair<>();
    for (DexAnnotationElement element : elements) {
      if (element.name == factory.createString("name")) {
        if (element.value.isDexValueString()) {
          result.setFirst(element.value.asDexValueString().getValue());
        }
      } else {
        assert element.name == factory.createString("accessFlags");
        result.setSecond(element.value.asDexValueInt().getValue());
      }
    }
    return result;
  }

  public static DexAnnotation createMemberClassesAnnotation(List<DexType> classes,
      DexItemFactory factory) {
    DexValue[] values = new DexValue[classes.size()];
    for (int i = 0; i < classes.size(); i++) {
      values[i] = new DexValueType(classes.get(i));
    }
    return createSystemValueAnnotation(factory.annotationMemberClasses, factory,
        new DexValueArray(values));
  }

  public static List<DexType> getMemberClassesFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationMemberClasses, annotation);
    if (value == null) {
      return null;
    }
    DexValueArray membersArray = value.asDexValueArray();
    List<DexType> types = new ArrayList<>(membersArray.getValues().length);
    for (DexValue elementValue : membersArray.getValues()) {
      types.add(elementValue.asDexValueType().value);
    }
    return types;
  }

  public static DexType getNestHostFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationNestHost, annotation);
    if (value == null) {
      return null;
    }
    return value.asDexValueType().getValue();
  }

  private static List<DexType> getTypesFromAnnotation(
      DexType annotationType, DexAnnotation annotation) {
    DexValue value = getSystemValueAnnotationValue(annotationType, annotation);
    if (value == null) {
      return null;
    }
    DexValueArray membersArray = value.asDexValueArray();
    List<DexType> types = new ArrayList<>(membersArray.getValues().length);
    for (DexValue elementValue : membersArray.getValues()) {
      types.add(elementValue.asDexValueType().value);
    }
    return types;
  }

  public static List<DexType> getNestMembersFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return getTypesFromAnnotation(factory.annotationNestMembers, annotation);
  }

  public static List<DexType> getPermittedSubclassesFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return getTypesFromAnnotation(factory.annotationPermittedSubclasses, annotation);
  }

  /** See {@link #createRecordAnnotation(DexProgramClass, AppView)} for the representation. */
  public static List<RecordComponentInfo> getRecordComponentInfoFromAnnotation(
      DexType type, DexAnnotation annotation, DexItemFactory factory, Origin origin) {
    DexValue componentNamesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentNames);
    DexValue componentTypesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentTypes);
    DexValue componentSignaturesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentSignatures);
    DexValue componentAnnotationVisibilitiesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord,
            annotation,
            factory.annotationRecordComponentAnnotationVisibilities);
    DexValue componentAnnotationsValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentAnnotations);

    if (componentNamesValue == null
        || componentTypesValue == null
        || componentSignaturesValue == null
        || componentAnnotationVisibilitiesValue == null
        || componentAnnotationsValue == null) {
      return null;
    }
    if (!componentNamesValue.isDexValueArray()
        || !componentTypesValue.isDexValueArray()
        || !componentSignaturesValue.isDexValueArray()
        || !componentAnnotationVisibilitiesValue.isDexValueArray()
        || !componentAnnotationsValue.isDexValueArray()) {
      return null;
    }
    DexValueArray componentNamesValueArray = componentNamesValue.asDexValueArray();
    DexValueArray componentTypesValueArray = componentTypesValue.asDexValueArray();
    DexValueArray componentSignaturesValueArray = componentSignaturesValue.asDexValueArray();
    DexValueArray componentAnnotationVisibilitiesValueArray =
        componentAnnotationVisibilitiesValue.asDexValueArray();
    DexValueArray componentAnnotationsValueArray = componentAnnotationsValue.asDexValueArray();
    if (componentNamesValueArray.size() != componentTypesValueArray.size()
        || componentNamesValueArray.size() != componentSignaturesValueArray.size()
        || componentNamesValueArray.size() != componentAnnotationVisibilitiesValueArray.size()
        || componentNamesValueArray.size() != componentAnnotationsValueArray.size()) {
      return null;
    }
    List<RecordComponentInfo> result = new ArrayList<>(componentNamesValueArray.size());
    for (int componentIndex = 0;
        componentIndex < componentNamesValueArray.size();
        componentIndex++) {
      DexValue nameValue = componentNamesValueArray.getValue(componentIndex);
      DexValue typeValue = componentTypesValueArray.getValue(componentIndex);
      DexValue signatureValue = componentSignaturesValueArray.getValue(componentIndex);
      DexValue visibilitiesValue =
          componentAnnotationVisibilitiesValueArray.getValue(componentIndex);
      DexValue annotationsValue = componentAnnotationsValueArray.getValue(componentIndex);
      if (!nameValue.isDexValueString()
          || !typeValue.isDexValueType()
          || !(signatureValue.isDexValueAnnotation() || signatureValue.isDexValueNull())
          || !visibilitiesValue.isDexValueArray()
          || !annotationsValue.isDexValueArray()) {
        return null;
      }
      DexValueArray visibilitiesValueArray = visibilitiesValue.asDexValueArray();
      DexValueArray annotationsValueArray = annotationsValue.asDexValueArray();
      if (visibilitiesValueArray.size() != annotationsValueArray.size()) {
        return null;
      }
      List<DexAnnotation> componentAnnotations = Collections.emptyList();
      if (annotationsValueArray.size() > 0) {
        componentAnnotations = new ArrayList<>(annotationsValueArray.size());
        for (int annotationIndex = 0;
            annotationIndex < annotationsValueArray.size();
            annotationIndex++) {
          DexValue visibilityValue = visibilitiesValueArray.getValue(annotationIndex);
          DexValue annotationValue = annotationsValueArray.getValue(annotationIndex);
          if (!visibilityValue.isDexValueByte() || !annotationValue.isDexValueAnnotation()) {
            return null;
          }
          componentAnnotations.add(
              new DexAnnotation(
                  visibilityValue.asDexValueByte().getValue(),
                  annotationValue.asDexValueAnnotation().getValue()));
        }
      }
      FieldTypeSignature componentSignature =
          GenericSignature.parseFieldTypeSignature(
              nameValue.asDexValueString().getValue().toString(),
              signatureValue.isDexValueAnnotation()
                  ? getSignature(signatureValue.asDexValueAnnotation().getValue())
                  : null,
              origin,
              factory,
              null);

      DexType componentType = typeValue.asDexValueType().getValue();
      DexString componentName = nameValue.asDexValueString().getValue();
      DexField componentField = factory.createField(type, componentType, componentName);
      result.add(new RecordComponentInfo(componentField, componentSignature, componentAnnotations));
    }
    return result;
  }

  public static DexAnnotation createSourceDebugExtensionAnnotation(DexValue value,
      DexItemFactory factory) {
    return new DexAnnotation(VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(factory.annotationSourceDebugExtension,
            new DexAnnotationElement[] {
              new DexAnnotationElement(factory.createString("value"), value)
            }));
  }

  public static DexAnnotation createMethodParametersAnnotation(DexValue[] names,
      DexValue[] accessFlags, DexItemFactory factory) {
    assert names.length == accessFlags.length;
    return new DexAnnotation(VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(factory.annotationMethodParameters,
            new DexAnnotationElement[]{
                new DexAnnotationElement(
                    factory.createString("names"),
                    new DexValueArray(names)),
                new DexAnnotationElement(
                    factory.createString("accessFlags"),
                    new DexValueArray(accessFlags))
            }));
  }

  public static DexAnnotation createAnnotationDefaultAnnotation(DexType type,
      List<DexAnnotationElement> defaults, DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationDefault, factory,
        new DexValueAnnotation(
            new DexEncodedAnnotation(type,
                defaults.toArray(DexAnnotationElement.EMPTY_ARRAY)))
    );
  }

  public static DexAnnotation createSignatureAnnotation(String signature, DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationSignature, factory,
        compressSignature(signature, factory));
  }

  public static DexAnnotation createNestHostAnnotation(
      NestHostClassAttribute host, DexItemFactory factory) {
    return createSystemValueAnnotation(
        factory.annotationNestHost, factory, new DexValue.DexValueType(host.getNestHost()));
  }

  public static DexAnnotation createNestMembersAnnotation(
      List<NestMemberClassAttribute> members, DexItemFactory factory) {
    List<DexValueType> list = new ArrayList<>(members.size());
    for (NestMemberClassAttribute member : members) {
      list.add(new DexValue.DexValueType(member.getNestMember()));
    }
    return createSystemValueAnnotation(
        factory.annotationNestMembers,
        factory,
        new DexValue.DexValueArray(list.toArray(DexValue.EMPTY_ARRAY)));
  }

  public static DexAnnotation createPermittedSubclassesAnnotation(
      List<PermittedSubclassAttribute> permittedSubclasses, DexItemFactory factory) {
    List<DexValueType> list = new ArrayList<>(permittedSubclasses.size());
    for (PermittedSubclassAttribute permittedSubclass : permittedSubclasses) {
      list.add(new DexValue.DexValueType(permittedSubclass.getPermittedSubclass()));
    }
    return createSystemValueAnnotation(
        factory.annotationPermittedSubclasses,
        factory,
        new DexValue.DexValueArray(list.toArray(DexValue.EMPTY_ARRAY)));
  }

  /**
   * Record component information is written to DEX as a system annotation named <code>
   * dalvik.annotation.Record</code> with the following content:
   *
   * <pre>
   *   componentAnnotationVisibilities byte[][]
   *   componentAnnotations Annotation[][]
   *   componentNames String[]
   *   componentSignatures Annotation[]  // Annotation dalvik.annotation.Signature or NULL
   *   componentTypes String[]
   * </pre>
   *
   * Each of the arrays have one element for each component.
   *
   * <p>Example of a two component record with two annotations on the first component and one on the
   * second and with a signature on the first component.
   *
   * <pre>
   * .annotation system Ldalvik/annotation/Record;
   *   componentAnnotationVisibilities = {
   *     {
   *       0x1,
   *       0x1
   *     },
   *     {
   *       0x1
   *     }
   *   }
   *   componentAnnotations = {
   *     {
   *       .subannotation LAnnotation1;
   *         value = "a"
   *       .end subannotation,
   *       .subannotation LAnnotation2;
   *         value = "c"
   *       .end subannotation
   *     },
   *     {
   *       .subannotation LAnnotation3;
   *         value = "z"
   *       .end subannotation
   *     }
   *   }
   *   componentNames = {
   *      "name",
   *      "age"
   *   }
   *   componentSignatures = {
   *     .subannotation Ldalvik/annotation/Signature;
   *       value = {
   *         "TX;"
   *       }
   *     .end subannotation,
   *     NULL
   *   }
   *   componentTypes = {
   *     Ljava/lang/CharSequence;,
   *     Ljava/lang/Object;
   *   }
   * .end annotation
   * </pre>
   */
  public static DexAnnotation createRecordAnnotation(DexProgramClass clazz, AppView<?> appView) {
    DexItemFactory factory = appView.dexItemFactory();
    int componentCount = clazz.getRecordComponents().size();
    DexValueString[] componentNames = new DexValueString[componentCount];
    DexValueType[] componentTypes = new DexValueType[componentCount];
    DexValue[] componentSignatures = new DexValue[componentCount];
    DexValueArray[] componentAnnotationVisibilities = new DexValueArray[componentCount];
    DexValueArray[] componentAnnotations = new DexValueArray[componentCount];
    for (int componentIndex = 0; componentIndex < componentCount; componentIndex++) {
      RecordComponentInfo info = clazz.getRecordComponents().get(componentIndex);
      componentNames[componentIndex] =
          new DexValueString(appView.getNamingLens().lookupName(info.getField()));
      componentTypes[componentIndex] = new DexValueType(info.getType());
      if (info.getSignature().hasNoSignature()) {
        componentSignatures[componentIndex] = DexValueNull.NULL;
      } else {
        componentSignatures[componentIndex] =
            new DexValueAnnotation(
                createSignatureAnnotation(info.getSignature().toString(), factory).annotation);
      }
      int annotationsSize = info.getAnnotations().size();
      DexValueByte[] visibilities = new DexValueByte[annotationsSize];
      DexValueAnnotation[] annotations = new DexValueAnnotation[annotationsSize];
      componentAnnotationVisibilities[componentIndex] = new DexValueArray(visibilities);
      componentAnnotations[componentIndex] = new DexValueArray(annotations);
      for (int annotationIndex = 0; annotationIndex < annotationsSize; annotationIndex++) {
        DexAnnotation annotation = info.getAnnotations().get(annotationIndex);
        visibilities[annotationIndex] = DexValueByte.create((byte) annotation.getVisibility());
        annotations[annotationIndex] = new DexValueAnnotation(annotation.annotation);
      }
    }

    if (appView.options().emitRecordAnnotationsExInDex) {
      return new DexAnnotation(
          VISIBILITY_SYSTEM,
          new DexEncodedAnnotation(
              factory.annotationRecord,
              new DexAnnotationElement[] {
                new DexAnnotationElement(
                    factory.annotationRecordComponentNames, new DexValueArray(componentNames)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentTypes, new DexValueArray(componentTypes)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentSignatures,
                    new DexValueArray(componentSignatures)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentAnnotationVisibilities,
                    new DexValueArray(componentAnnotationVisibilities)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentAnnotations,
                    new DexValueArray(componentAnnotations))
              }));
    } else {
      return new DexAnnotation(
          VISIBILITY_SYSTEM,
          new DexEncodedAnnotation(
              factory.annotationRecord,
              new DexAnnotationElement[] {
                new DexAnnotationElement(
                    factory.annotationRecordComponentNames, new DexValueArray(componentNames)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentTypes, new DexValueArray(componentTypes))
              }));
    }
  }

  public static String getSignature(DexAnnotation signatureAnnotation) {
    return getSignature(signatureAnnotation.annotation);
  }

  public static String getSignature(DexEncodedAnnotation signatureAnnotation) {
    return getSignature(signatureAnnotation.elements[0].value.asDexValueArray());
  }

  public static String getSignature(DexValueArray elements) {
    StringBuilder signature = new StringBuilder();
    for (DexValue element : elements.getValues()) {
      signature.append(element.asDexValueString().value.toString());
    }
    return signature.toString();
  }

  public static String getSignature(DexAnnotationSet signatureAnnotations, DexItemFactory factory) {
    DexAnnotation signature = signatureAnnotations.getFirstMatching(factory.annotationSignature);
    return signature == null ? null : getSignature(signature);
  }

  public static DexAnnotation createThrowsAnnotation(DexValue[] exceptions,
      DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationThrows, factory,
        new DexValueArray(exceptions));
  }

  private static DexAnnotation createSystemValueAnnotation(DexType type, DexItemFactory factory,
      DexValue value) {
    return new DexAnnotation(VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(type, new DexAnnotationElement[]{
            new DexAnnotationElement(factory.createString("value"), value)
        }));
  }

  private static DexValue getSystemValueAnnotationValue(DexType type, DexAnnotation annotation) {
    assert annotation.visibility == VISIBILITY_SYSTEM;
    assert annotation.annotation.type == type;
    return annotation.annotation.elements.length == 0
        ? null
        : annotation.annotation.elements[0].value;
  }

  private static DexValue getSystemValueAnnotationValueWithName(
      DexType type, DexAnnotation annotation, DexString name) {
    assert annotation.visibility == VISIBILITY_SYSTEM;
    assert annotation.getAnnotationType() == type;
    for (DexAnnotationElement element : annotation.annotation.elements) {
      if (element.name == name) {
        return element.value;
      }
    }
    return null;
  }

  public static boolean isThrowingAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationThrows;
  }

  public static boolean isSignatureAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationSignature;

  }

  public static boolean isAnnotationDefaultAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationDefault;
  }

  public static boolean isJavaLangRetentionAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return annotation.getAnnotationType() == factory.retentionType;
  }

  public static boolean isSourceDebugExtension(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationSourceDebugExtension;
  }

  public static boolean isParameterNameAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationMethodParameters;
  }

  /**
   * As a simple heuristic for compressing a signature by splitting on fully qualified class names
   * and make them individual part. All other parts of the signature are simply grouped and separate
   * the names.
   * For examples, "()Ljava/lang/List<Lfoo/bar/Baz;>;" splits into:
   * <pre>
   *   ["()", "Ljava/lang/List<", "Lfoo/bar/Baz;", ">;"]
   * </pre>
   */
  private static DexValue compressSignature(String signature, DexItemFactory factory) {
    final int length = signature.length();
    List<DexValue> parts = new ArrayList<>();

    for (int at = 0; at < length; /*at*/) {
      char c = signature.charAt(at);
      int endAt = at + 1;
      if (c == 'L') {
        // Scan to ';' or '<' and consume them.
        while (endAt < length) {
          c = signature.charAt(endAt);
          if (c == ';' || c == '<') {
            endAt++;
            break;
          }
          endAt++;
        }
      } else {
        // Scan to 'L' without consuming it.
        while (endAt < length) {
          c = signature.charAt(endAt);
          if (c == 'L') {
            break;
          }
          endAt++;
        }
      }

      parts.add(toDexValue(signature.substring(at, endAt), factory));
      at = endAt;
    }

    return new DexValueArray(parts.toArray(DexValue.EMPTY_ARRAY));
  }

  private static DexValue toDexValue(String string, DexItemFactory factory) {
    return new DexValueString(factory.createString(string));
  }

  public static DexAnnotation createAnnotationSynthesizedClass(
      SyntheticKind kind, DexItemFactory dexItemFactory, ComputedApiLevel computedApiLevel) {
    DexString versionHash =
        dexItemFactory.createString(dexItemFactory.getSyntheticNaming().getVersionHash());
    DexAnnotationElement kindElement =
        new DexAnnotationElement(dexItemFactory.kindString, DexValueInt.create(kind.getId()));
    DexAnnotationElement versionHashElement =
        new DexAnnotationElement(dexItemFactory.versionHashString, new DexValueString(versionHash));
    int apiLevel = getApiLevelForSerialization(computedApiLevel);
    DexAnnotationElement apiLevelElement =
        new DexAnnotationElement(dexItemFactory.apiLevelString, DexValueInt.create(apiLevel));
    DexAnnotationElement[] elements =
        new DexAnnotationElement[] {apiLevelElement, kindElement, versionHashElement};
    return new DexAnnotation(
        VISIBILITY_BUILD,
        new DexEncodedAnnotation(dexItemFactory.annotationSynthesizedClass, elements));
  }

  public static boolean hasSynthesizedClassAnnotation(
      DexAnnotationSet annotations,
      DexItemFactory factory,
      SyntheticItems synthetics,
      AndroidApiLevelCompute apiLevelCompute) {
    return getSynthesizedClassAnnotationInfo(annotations, factory, synthetics, apiLevelCompute)
        != null;
  }

  public static SynthesizedAnnotationClassInfo getSynthesizedClassAnnotationInfo(
      DexAnnotationSet annotations,
      DexItemFactory factory,
      SyntheticItems synthetics,
      AndroidApiLevelCompute apiLevelCompute) {
    if (annotations.size() != 1) {
      return null;
    }
    DexAnnotation annotation = annotations.annotations[0];
    if (annotation.annotation.type != factory.annotationSynthesizedClass) {
      return null;
    }
    int length = annotation.annotation.elements.length;
    if (length != 3) {
      return null;
    }
    assert factory.kindString.isLessThan(factory.versionHashString);
    DexAnnotationElement apiLevelElement = annotation.annotation.elements[0];
    DexAnnotationElement kindElement = annotation.annotation.elements[1];
    DexAnnotationElement versionHashElement = annotation.annotation.elements[2];
    if (kindElement.name != factory.kindString) {
      return null;
    }
    if (!kindElement.value.isDexValueInt()) {
      return null;
    }
    if (versionHashElement.name != factory.versionHashString) {
      return null;
    }
    if (!versionHashElement.value.isDexValueString()) {
      return null;
    }
    if (apiLevelElement.name != factory.apiLevelString || !apiLevelElement.value.isDexValueInt()) {
      return null;
    }
    String currentVersionHash = synthetics.getNaming().getVersionHash();
    String syntheticVersionHash = versionHashElement.value.asDexValueString().getValue().toString();
    if (!currentVersionHash.equals(syntheticVersionHash)) {
      return null;
    }
    int apiLevelValue = apiLevelElement.value.asDexValueInt().getValue();
    ComputedApiLevel computedApiLevel = getSerializedApiLevel(apiLevelCompute, apiLevelValue);
    SyntheticKind syntheticKind =
        synthetics.getNaming().fromId(kindElement.value.asDexValueInt().getValue());
    assert syntheticKind != synthetics.getNaming().API_MODEL_OUTLINE
        || computedApiLevel.isKnownApiLevel();
    return SynthesizedAnnotationClassInfo.create(syntheticKind, computedApiLevel);
  }

  private static int getApiLevelForSerialization(ComputedApiLevel computedApiLevel) {
    if (computedApiLevel.isNotSetApiLevel()) {
      return NOT_SET_API_LEVEL;
    } else if (computedApiLevel.isUnknownApiLevel()) {
      return UNKNOWN_API_LEVEL;
    } else {
      assert computedApiLevel.isKnownApiLevel();
      return computedApiLevel.asKnownApiLevel().getApiLevel().getLevel();
    }
  }

  private static ComputedApiLevel getSerializedApiLevel(
      AndroidApiLevelCompute apiLevelCompute, int apiLevelValue) {
    if (apiLevelValue == NOT_SET_API_LEVEL) {
      return ComputedApiLevel.notSet();
    } else if (apiLevelValue == UNKNOWN_API_LEVEL) {
      return ComputedApiLevel.unknown();
    } else {
      return apiLevelCompute.of(AndroidApiLevel.getAndroidApiLevel(apiLevelValue));
    }
  }

  public DexAnnotation rewrite(Function<DexEncodedAnnotation, DexEncodedAnnotation> rewriter) {
    DexEncodedAnnotation rewritten = rewriter.apply(annotation);
    if (rewritten == annotation) {
      return this;
    }
    if (rewritten == null) {
      return null;
    }
    return new DexAnnotation(visibility, rewritten);
  }

  public static class SynthesizedAnnotationClassInfo {

    private final SyntheticKind syntheticKind;
    private final ComputedApiLevel computedApiLevel;

    private SynthesizedAnnotationClassInfo(
        SyntheticKind syntheticKind, ComputedApiLevel computedApiLevel) {
      this.syntheticKind = syntheticKind;
      this.computedApiLevel = computedApiLevel;
    }

    private static SynthesizedAnnotationClassInfo create(
        SyntheticKind syntheticKind, ComputedApiLevel computedApiLevel) {
      return new SynthesizedAnnotationClassInfo(syntheticKind, computedApiLevel);
    }

    public SyntheticKind getSyntheticKind() {
      return syntheticKind;
    }

    public ComputedApiLevel getComputedApiLevel() {
      return computedApiLevel;
    }
  }
}
