// 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.utils;

import static org.junit.Assert.assertTrue;

import com.android.tools.r8.StringResource;
import com.android.tools.r8.code.Const4;
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.Goto;
import com.android.tools.r8.code.IfEqz;
import com.android.tools.r8.code.IfNez;
import com.android.tools.r8.code.Iget;
import com.android.tools.r8.code.IgetBoolean;
import com.android.tools.r8.code.IgetByte;
import com.android.tools.r8.code.IgetChar;
import com.android.tools.r8.code.IgetObject;
import com.android.tools.r8.code.IgetShort;
import com.android.tools.r8.code.IgetWide;
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.Iput;
import com.android.tools.r8.code.IputBoolean;
import com.android.tools.r8.code.IputByte;
import com.android.tools.r8.code.IputChar;
import com.android.tools.r8.code.IputObject;
import com.android.tools.r8.code.IputShort;
import com.android.tools.r8.code.IputWide;
import com.android.tools.r8.code.Nop;
import com.android.tools.r8.code.ReturnVoid;
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.code.Sput;
import com.android.tools.r8.code.SputBoolean;
import com.android.tools.r8.code.SputByte;
import com.android.tools.r8.code.SputChar;
import com.android.tools.r8.code.SputObject;
import com.android.tools.r8.code.SputShort;
import com.android.tools.r8.code.SputWide;
import com.android.tools.r8.code.Throw;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexEncodedAnnotation;
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.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.ClassNamingForNameMapper;
import com.android.tools.r8.naming.MemberNaming;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
import com.android.tools.r8.naming.signature.GenericSignatureAction;
import com.android.tools.r8.naming.signature.GenericSignatureParser;
import com.android.tools.r8.smali.SmaliBuilder;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

public class DexInspector {

  private final DexApplication application;
  private final DexItemFactory dexItemFactory;
  private final ClassNameMapper mapping;
  private final BiMap<String, String> originalToObfuscatedMapping;

  private final InstructionSubjectFactory factory = new InstructionSubjectFactory();

  public static MethodSignature MAIN =
      new MethodSignature("main", "void", new String[]{"java.lang.String[]"});

  public DexInspector(Path file, String mappingFile) throws IOException, ExecutionException {
    this(Collections.singletonList(file), mappingFile);
  }

  public DexInspector(Path file) throws IOException, ExecutionException {
    this(Collections.singletonList(file), null);
  }

  public DexInspector(List<Path> files) throws IOException, ExecutionException {
    this(files, null);
  }

  public DexInspector(List<Path> files, String mappingFile)
      throws IOException, ExecutionException {
    if (mappingFile != null) {
      this.mapping = ClassNameMapper.mapperFromFile(Paths.get(mappingFile));
      originalToObfuscatedMapping = this.mapping.getObfuscatedToOriginalMapping().inverse();
    } else {
      this.mapping = null;
      originalToObfuscatedMapping = null;
    }
    Timing timing = new Timing("DexInspector");
    InternalOptions options = new InternalOptions();
    dexItemFactory = options.itemFactory;
    AndroidApp input = AndroidApp.builder().addProgramFiles(files).build();
    application = new ApplicationReader(input, options, timing).read();
  }

  public DexInspector(AndroidApp app) throws IOException, ExecutionException {
    this(
        new ApplicationReader(app, new InternalOptions(), new Timing("DexInspector"))
            .read(app.getProguardMapOutputData()));
  }

  public DexInspector(AndroidApp app, Consumer<InternalOptions> optionsConsumer)
      throws IOException, ExecutionException {
    this(
        new ApplicationReader(app, runOptionsConsumer(optionsConsumer), new Timing("DexInspector"))
            .read(app.getProguardMapOutputData()));
  }

  private static InternalOptions runOptionsConsumer(Consumer<InternalOptions> optionsConsumer) {
    InternalOptions internalOptions = new InternalOptions();
    optionsConsumer.accept(internalOptions);
    return internalOptions;
  }

  public DexInspector(AndroidApp app, Path proguardMap) throws IOException, ExecutionException {
    this(
        new ApplicationReader(app, new InternalOptions(), new Timing("DexInspector"))
            .read(StringResource.fromFile(proguardMap)));
  }

  public DexInspector(DexApplication application) {
    dexItemFactory = application.dexItemFactory;
    this.application = application;
    this.mapping = application.getProguardMap();
    originalToObfuscatedMapping =
        mapping == null ? null : mapping.getObfuscatedToOriginalMapping().inverse();
  }

  public DexItemFactory getFactory() {
    return dexItemFactory;
  }

  private DexType toDexType(String string) {
    return dexItemFactory.createType(DescriptorUtils.javaTypeToDescriptor(string));
  }

  private DexType toDexTypeIgnorePrimitives(String string) {
    return dexItemFactory.createType(DescriptorUtils.javaTypeToDescriptorIgnorePrimitives(string));
  }

  private static <S, T extends Subject> void forAll(S[] items,
      BiFunction<S, FoundClassSubject, ? extends T> constructor,
      FoundClassSubject clazz,
      Consumer<T> consumer) {
    for (S item : items) {
      consumer.accept(constructor.apply(item, clazz));
    }
  }

  private static <S, T extends Subject> void forAll(Iterable<S> items, Function<S, T> constructor,
      Consumer<T> consumer) {
    for (S item : items) {
      consumer.accept(constructor.apply(item));
    }
  }

  DexAnnotation findAnnotation(String name, DexAnnotationSet annotations) {
    for (DexAnnotation annotation : annotations.annotations) {
      DexType type = annotation.annotation.type;
      String original = mapping == null ? type.toSourceString() : mapping.originalNameOf(type);
      if (original.equals(name)) {
        return annotation;
      }
    }
    return null;
  }

  public String getFinalSignatureAttribute(DexAnnotationSet annotations) {
    DexAnnotation annotation =
        findAnnotation("dalvik.annotation.Signature", annotations);
    if (annotation == null) {
      return null;
    }
    assert annotation.annotation.elements.length == 1;
    DexAnnotationElement element = annotation.annotation.elements[0];
    assert element.value instanceof DexValueArray;
    StringBuilder builder = new StringBuilder();
    DexValueArray valueArray = (DexValueArray) element.value;
    for (DexValue value : valueArray.getValues()) {
      assertTrue(value instanceof DexValueString);
      DexValueString s = (DexValueString) value;
      builder.append(s.getValue());
    }
    return builder.toString();
  }

  public String getOriginalSignatureAttribute(
      DexAnnotationSet annotations, BiConsumer<GenericSignatureParser, String> parse) {
    String finalSignature = getFinalSignatureAttribute(annotations);
    if (finalSignature == null || mapping == null) {
      return finalSignature;
    }

    GenericSignatureGenerater rewriter = new GenericSignatureGenerater();
    GenericSignatureParser<String> parser = new GenericSignatureParser<>(rewriter);
    parse.accept(parser, finalSignature);
    return rewriter.getSignature();
  }


  public ClassSubject clazz(Class clazz) {
    return clazz(clazz.getTypeName());
  }

  /**
   * Lookup a class by name. This allows both original and obfuscated names.
   */
  public ClassSubject clazz(String name) {
    ClassNamingForNameMapper naming = null;
    if (mapping != null) {
      String obfuscated = originalToObfuscatedMapping.get(name);
      if (obfuscated != null) {
        naming = mapping.getClassNaming(obfuscated);
        name = obfuscated;
      } else {
        // Figure out if the name is an already obfuscated name.
        String original = originalToObfuscatedMapping.inverse().get(name);
        if (original != null) {
          naming = mapping.getClassNaming(name);
        }
      }
    }
    DexClass clazz = application.definitionFor(toDexTypeIgnorePrimitives(name));
    if (clazz == null) {
      return new AbsentClassSubject();
    }
    return new FoundClassSubject(clazz, naming);
  }

  public void forAllClasses(Consumer<FoundClassSubject> inspection) {
    forAll(application.classes(), cls -> {
      ClassSubject subject = clazz(cls.type.toSourceString());
      assert subject.isPresent();
      return (FoundClassSubject) subject;
    }, inspection);
  }

  public List<FoundClassSubject> allClasses() {
    ImmutableList.Builder<FoundClassSubject> builder = ImmutableList.builder();
    forAllClasses(builder::add);
    return builder.build();
  }

  public MethodSubject method(Method method) {
    ClassSubject clazz = clazz(method.getDeclaringClass());
    if (!clazz.isPresent()) {
      return new AbsentMethodSubject();
    }
    return clazz.method(method);
  }

  private String getObfuscatedTypeName(String originalTypeName) {
    String obfuscatedType = null;
    if (mapping != null) {
      obfuscatedType = originalToObfuscatedMapping.get(originalTypeName);
    }
    obfuscatedType = obfuscatedType == null ? originalTypeName : obfuscatedType;
    return obfuscatedType;
  }

  public abstract class Subject {

    public abstract boolean isPresent();
    public abstract boolean isRenamed();
  }

  public abstract class AnnotationSubject extends Subject {

    public abstract DexEncodedAnnotation getAnnotation();
  }

  public class FoundAnnotationSubject extends AnnotationSubject {

    private final DexAnnotation annotation;

    private FoundAnnotationSubject(DexAnnotation annotation) {
      this.annotation = annotation;
    }

    @Override
    public boolean isPresent() {
      return true;
    }

    @Override
    public boolean isRenamed() {
      return false;
    }

    @Override
    public DexEncodedAnnotation getAnnotation() {
      return annotation.annotation;
    }
  }

  public class AbsentAnnotationSubject extends AnnotationSubject {

    @Override
    public boolean isPresent() {
      return false;
    }

    @Override
    public boolean isRenamed() {
      return false;
    }

    @Override
    public DexEncodedAnnotation getAnnotation() {
      throw new UnsupportedOperationException();
    }
  }


  public abstract class ClassSubject extends Subject {

    public abstract void forAllMethods(Consumer<FoundMethodSubject> inspection);

    public MethodSubject method(Method method) {
      List<String> parameters = new ArrayList<>();
      for (Class<?> parameterType : method.getParameterTypes()) {
        parameters.add(parameterType.getTypeName());
      }
      return method(method.getReturnType().getTypeName(), method.getName(), parameters);
    }

    public abstract MethodSubject method(String returnType, String name, List<String> parameters);

    public MethodSubject clinit() {
      return method("void", "<clinit>", ImmutableList.of());
    }

    public MethodSubject init(List<String> parameters) {
      return method("void", "<init>", parameters);
    }

    public MethodSubject method(MethodSignature signature) {
      return method(signature.type, signature.name, ImmutableList.copyOf(signature.parameters));
    }

    public MethodSubject method(SmaliBuilder.MethodSignature signature) {
      return method(
          signature.returnType, signature.name, ImmutableList.copyOf(signature.parameterTypes));
    }

    public abstract void forAllFields(Consumer<FoundFieldSubject> inspection);

    public abstract FieldSubject field(String type, String name);

    public abstract boolean isAbstract();

    public abstract boolean isAnnotation();

    public String dumpMethods() {
      StringBuilder dump = new StringBuilder();
      forAllMethods((FoundMethodSubject method) ->
          dump.append(method.getMethod().toString())
              .append(method.getMethod().codeToString()));
      return dump.toString();
    }

    public abstract DexClass getDexClass();

    public abstract AnnotationSubject annotation(String name);

    public abstract String getOriginalName();

    public abstract String getOriginalDescriptor();

    public abstract String getFinalDescriptor();

    public abstract boolean isMemberClass();

    public abstract boolean isLocalClass();

    public abstract boolean isAnonymousClass();

    public abstract String getOriginalSignatureAttribute();

    public abstract String getFinalSignatureAttribute();
  }

  private class AbsentClassSubject extends ClassSubject {

    @Override
    public boolean isPresent() {
      return false;
    }

    @Override
    public void forAllMethods(Consumer<FoundMethodSubject> inspection) {
    }

    @Override
    public MethodSubject method(String returnType, String name, List<String> parameters) {
      return new AbsentMethodSubject();
    }

    @Override
    public void forAllFields(Consumer<FoundFieldSubject> inspection) {
    }

    @Override
    public FieldSubject field(String type, String name) {
      return new AbsentFieldSubject();
    }

    @Override
    public boolean isAbstract() {
      return false;
    }

    @Override
    public boolean isAnnotation() {
      return false;
    }

    @Override
    public DexClass getDexClass() {
      return null;
    }

    @Override
    public AnnotationSubject annotation(String name) {
      return new AbsentAnnotationSubject();
    }

    @Override
    public String getOriginalName() {
      return null;
    }

    @Override
    public String getOriginalDescriptor() {
      return null;
    }

    @Override
    public String getFinalDescriptor() {
      return null;
    }

    @Override
    public boolean isRenamed() {
      return false;
    }

    @Override
    public boolean isMemberClass() {
      return false;
    }

    @Override
    public boolean isLocalClass() {
      return false;
    }

    @Override
    public boolean isAnonymousClass() {
      return false;
    }

    @Override
    public String getOriginalSignatureAttribute() {
      return null;
    }

    @Override
    public String getFinalSignatureAttribute() {
      return null;
    }
  }

  public class FoundClassSubject extends ClassSubject {

    private final DexClass dexClass;
    private final ClassNamingForNameMapper naming;

    private FoundClassSubject(DexClass dexClass, ClassNamingForNameMapper naming) {
      this.dexClass = dexClass;
      this.naming = naming;
    }

    @Override
    public boolean isPresent() {
      return true;
    }

    @Override
    public void forAllMethods(Consumer<FoundMethodSubject> inspection) {
      forAll(dexClass.directMethods(), FoundMethodSubject::new, this, inspection);
      forAll(dexClass.virtualMethods(), FoundMethodSubject::new, this, inspection);
    }

    @Override
    public MethodSubject method(String returnType, String name, List<String> parameters) {
      DexType[] parameterTypes = new DexType[parameters.size()];
      for (int i = 0; i < parameters.size(); i++) {
        parameterTypes[i] = toDexType(getObfuscatedTypeName(parameters.get(i)));
      }
      DexProto proto = dexItemFactory.createProto(toDexType(getObfuscatedTypeName(returnType)),
          parameterTypes);
      if (naming != null) {
        String[] parameterStrings = new String[parameterTypes.length];
        Signature signature = new MethodSignature(name, returnType,
            parameters.toArray(parameterStrings));
        MemberNaming methodNaming = naming.lookupByOriginalSignature(signature);
        if (methodNaming != null) {
          name = methodNaming.getRenamedName();
        }
      }
      DexMethod dexMethod =
          dexItemFactory.createMethod(dexClass.type, proto, dexItemFactory.createString(name));
      DexEncodedMethod encoded = findMethod(dexClass.directMethods(), dexMethod);
      if (encoded == null) {
        encoded = findMethod(dexClass.virtualMethods(), dexMethod);
      }
      return encoded == null ? new AbsentMethodSubject() : new FoundMethodSubject(encoded, this);
    }

    private DexEncodedMethod findMethod(DexEncodedMethod[] methods, DexMethod dexMethod) {
      for (DexEncodedMethod method : methods) {
        if (method.method.equals(dexMethod)) {
          return method;
        }
      }
      return null;
    }

    @Override
    public void forAllFields(Consumer<FoundFieldSubject> inspection) {
      forAll(dexClass.staticFields(), FoundFieldSubject::new, this, inspection);
      forAll(dexClass.instanceFields(), FoundFieldSubject::new, this, inspection);
    }

    @Override
    public FieldSubject field(String type, String name) {
      String obfuscatedType = getObfuscatedTypeName(type);
      MemberNaming fieldNaming = null;
      if (naming != null) {
        fieldNaming = naming.lookupByOriginalSignature(
            new FieldSignature(name, type));
      }
      String obfuscatedName = fieldNaming == null ? name : fieldNaming.getRenamedName();

      DexField field = dexItemFactory.createField(dexClass.type,
          toDexType(obfuscatedType), dexItemFactory.createString(obfuscatedName));
      DexEncodedField encoded = findField(dexClass.staticFields(), field);
      if (encoded == null) {
        encoded = findField(dexClass.instanceFields(), field);
      }
      return encoded == null ? new AbsentFieldSubject() : new FoundFieldSubject(encoded, this);
    }

    @Override
    public boolean isAbstract() {
      return dexClass.accessFlags.isAbstract();
    }

    @Override
    public boolean isAnnotation() {
      return dexClass.accessFlags.isAnnotation();
    }

    private DexEncodedField findField(DexEncodedField[] fields, DexField dexField) {
      for (DexEncodedField field : fields) {
        if (field.field.equals(dexField)) {
          return field;
        }
      }
      return null;
    }

    @Override
    public DexClass getDexClass() {
      return dexClass;
    }

    @Override
    public AnnotationSubject annotation(String name) {
      // Ensure we don't check for annotations represented as attributes.
      assert !name.endsWith("EnclosingClass")
          && !name.endsWith("EnclosingMethod")
          && !name.endsWith("InnerClass");
      DexAnnotation annotation = findAnnotation(name, dexClass.annotations);
      return annotation == null
          ? new AbsentAnnotationSubject()
          : new FoundAnnotationSubject(annotation);
    }

    @Override
    public String getOriginalName() {
      if (naming != null) {
        return naming.originalName;
      } else {
        return DescriptorUtils.descriptorToJavaType(getFinalDescriptor());
      }
    }

    @Override
    public String getOriginalDescriptor() {
      if (naming != null) {
        return DescriptorUtils.javaTypeToDescriptor(naming.originalName);
      } else {
        return getFinalDescriptor();
      }
    }

    @Override
    public String getFinalDescriptor() {
      return dexClass.type.descriptor.toString();
    }

    @Override
    public boolean isRenamed() {
      return naming != null && !getFinalDescriptor().equals(getOriginalDescriptor());
    }

    private InnerClassAttribute getInnerClassAttribute() {
      for (InnerClassAttribute innerClassAttribute : dexClass.getInnerClasses()) {
        if (dexClass.type == innerClassAttribute.getInner()) {
          return innerClassAttribute;
        }
      }
      return null;
    }

    @Override
    public boolean isLocalClass() {
      InnerClassAttribute innerClass = getInnerClassAttribute();
      return innerClass != null
          && innerClass.isNamed()
          && dexClass.getEnclosingMethod() != null;
    }

    @Override
    public boolean isMemberClass() {
      InnerClassAttribute innerClass = getInnerClassAttribute();
      return innerClass != null
          && innerClass.getOuter() != null
          && innerClass.isNamed()
          && dexClass.getEnclosingMethod() == null;
    }

    @Override
    public boolean isAnonymousClass() {
      InnerClassAttribute innerClass = getInnerClassAttribute();
      return innerClass != null
          && innerClass.isAnonymous()
          && dexClass.getEnclosingMethod() != null;
    }

    @Override
    public String getOriginalSignatureAttribute() {
      return DexInspector.this.getOriginalSignatureAttribute(
          dexClass.annotations, GenericSignatureParser::parseClassSignature);
    }

    @Override
    public String getFinalSignatureAttribute() {
      return DexInspector.this.getFinalSignatureAttribute(dexClass.annotations);
    }

    @Override
    public String toString() {
      return dexClass.toSourceString();
    }
  }

  public abstract class MemberSubject extends Subject {

    public abstract boolean isStatic();

    public abstract boolean isFinal();

    public abstract Signature getOriginalSignature();

    public abstract Signature getFinalSignature();

    public String getOriginalName() {
      Signature originalSignature = getOriginalSignature();
      return originalSignature == null ? null : originalSignature.name;
    }

    public String getFinalName() {
      Signature finalSignature = getFinalSignature();
      return finalSignature == null ? null : finalSignature.name;
    }
  }

  public abstract class MethodSubject extends MemberSubject {

    public abstract boolean isAbstract();

    public abstract boolean isBridge();

    public abstract boolean isInstanceInitializer();

    public abstract boolean isClassInitializer();

    public abstract String getOriginalSignatureAttribute();

    public abstract String getFinalSignatureAttribute();

    public abstract DexEncodedMethod getMethod();

    public Iterator<InstructionSubject> iterateInstructions() {
      return null;
    }

    public <T extends InstructionSubject> Iterator<T> iterateInstructions(
        Predicate<InstructionSubject> filter) {
      return null;
    }
  }

  public class AbsentMethodSubject extends MethodSubject {

    @Override
    public boolean isPresent() {
      return false;
    }

    @Override
    public boolean isRenamed() {
      return false;
    }

    @Override
    public boolean isStatic() {
      return false;
    }

    @Override
    public boolean isFinal() {
      return false;
    }

    @Override
    public boolean isAbstract() {
      return false;
    }

    @Override
    public boolean isBridge() {
      return false;
    }

    @Override
    public boolean isInstanceInitializer() {
      return false;
    }

    @Override
    public boolean isClassInitializer() {
      return false;
    }

    @Override
    public DexEncodedMethod getMethod() {
      return null;
    }

    @Override
    public Signature getOriginalSignature() {
      return null;
    }

    @Override
    public Signature getFinalSignature() {
      return null;
    }

    @Override
    public String getOriginalSignatureAttribute() {
      return null;
    }

    @Override
    public String getFinalSignatureAttribute() {
      return null;
    }
  }

  public class FoundMethodSubject extends MethodSubject {

    private final FoundClassSubject clazz;
    private final DexEncodedMethod dexMethod;

    public FoundMethodSubject(DexEncodedMethod encoded, FoundClassSubject clazz) {
      this.clazz = clazz;
      this.dexMethod = encoded;
    }

    @Override
    public boolean isPresent() {
      return true;
    }

    @Override
    public boolean isRenamed() {
      return clazz.naming != null && !getFinalSignature().name.equals(getOriginalSignature().name);
    }

    @Override
    public boolean isStatic() {
      return dexMethod.accessFlags.isStatic();
    }

    @Override
    public boolean isFinal() {
      return dexMethod.accessFlags.isFinal();
    }

    @Override
    public boolean isAbstract() {
      return dexMethod.accessFlags.isAbstract();
    }

    @Override
    public boolean isBridge() {
      return dexMethod.accessFlags.isBridge();
    }

    @Override
    public boolean isInstanceInitializer() {
      return dexMethod.isInstanceInitializer();
    }

    @Override
    public boolean isClassInitializer() {
      return dexMethod.isClassInitializer();
    }

    @Override
    public DexEncodedMethod getMethod() {
      return dexMethod;
    }

    @Override
    public MethodSignature getOriginalSignature() {
      MethodSignature signature = getFinalSignature();
      MemberNaming memberNaming = clazz.naming != null ? clazz.naming.lookup(signature) : null;
      return memberNaming != null
          ? (MethodSignature) memberNaming.getOriginalSignature()
          : signature;
    }

    @Override
    public MethodSignature getFinalSignature() {
      return MemberNaming.MethodSignature.fromDexMethod(dexMethod.method);
    }

    @Override
    public String getOriginalSignatureAttribute() {
      return DexInspector.this.getOriginalSignatureAttribute(
          dexMethod.annotations, GenericSignatureParser::parseMethodSignature);
    }

    @Override
    public String getFinalSignatureAttribute() {
      return DexInspector.this.getFinalSignatureAttribute(dexMethod.annotations);
    }

    @Override
    public Iterator<InstructionSubject> iterateInstructions() {
      return new InstructionIterator(this);
    }

    @Override
    public <T extends InstructionSubject> Iterator<T> iterateInstructions(
        Predicate<InstructionSubject> filter) {
      return new FilteredInstructionIterator<>(this, filter);
    }

    @Override
    public String toString() {
      return dexMethod.toSourceString();
    }
  }

  public abstract class FieldSubject extends MemberSubject {
    public abstract boolean hasExplicitStaticValue();

    public abstract DexEncodedField getField();

    public abstract DexValue getStaticValue();

    public abstract boolean isRenamed();

    public abstract String getOriginalSignatureAttribute();

    public abstract String getFinalSignatureAttribute();
  }

  public class AbsentFieldSubject extends FieldSubject {

    @Override
    public boolean isStatic() {
      return false;
    }

    @Override
    public boolean isFinal() {
      return false;
    }

    @Override
    public boolean isPresent() {
      return false;
    }

    @Override
    public boolean isRenamed() {
      return false;
    }

    @Override
    public Signature getOriginalSignature() {
      return null;
    }

    @Override
    public Signature getFinalSignature() {
      return null;
    }

    @Override
    public boolean hasExplicitStaticValue() {
      return false;
    }

    @Override
    public DexValue getStaticValue() {
      return null;
    }

    @Override
    public DexEncodedField getField() {
      return null;
    }

    @Override
    public String getOriginalSignatureAttribute() {
      return null;
    }

    @Override
    public String getFinalSignatureAttribute() {
      return null;
    }
  }

  public class FoundFieldSubject extends FieldSubject {

    private final FoundClassSubject clazz;
    private final DexEncodedField dexField;

    public FoundFieldSubject(DexEncodedField dexField, FoundClassSubject clazz) {
      this.clazz = clazz;
      this.dexField = dexField;
    }

    @Override
    public boolean isStatic() {
      return dexField.accessFlags.isStatic();
    }

    @Override
    public boolean isFinal() {
      return dexField.accessFlags.isFinal();
    }

    @Override
    public boolean isPresent() {
      return true;
    }

    @Override
    public boolean isRenamed() {
      return clazz.naming != null && !getFinalSignature().name.equals(getOriginalSignature().name);
    }


    public TypeSubject type() {
      return new TypeSubject(dexField.field.type);
    }

    @Override
    public FieldSignature getOriginalSignature() {
      FieldSignature signature = getFinalSignature();
      MemberNaming memberNaming = clazz.naming != null ? clazz.naming.lookup(signature) : null;
      return memberNaming != null
          ? (FieldSignature) memberNaming.getOriginalSignature()
          : signature;
    }

    @Override
    public FieldSignature getFinalSignature() {
      return MemberNaming.FieldSignature.fromDexField(dexField.field);
    }

    @Override
    public boolean hasExplicitStaticValue() {
      return isStatic() && dexField.hasExplicitStaticValue();
    }

    @Override
    public DexValue getStaticValue() {
      return dexField.getStaticValue();
    }

    @Override
    public DexEncodedField getField() {
      return dexField;
    }

    @Override
    public String getOriginalSignatureAttribute() {
      return DexInspector.this.getOriginalSignatureAttribute(
          dexField.annotations, GenericSignatureParser::parseFieldSignature);
    }

    @Override
    public String getFinalSignatureAttribute() {
      return DexInspector.this.getFinalSignatureAttribute(dexField.annotations);
    }

    @Override
    public String toString() {
      return dexField.toSourceString();
    }
  }

  public class TypeSubject extends Subject {

    private final DexType dexType;

    TypeSubject(DexType dexType) {
      this.dexType = dexType;
    }

    @Override
    public boolean isPresent() {
      return true;
    }

    @Override
    public boolean isRenamed() {
      return false;
    }

    public boolean is(String type) {
      return dexType.equals(toDexType(type));
    }

    public String toString() {
      return dexType.toSourceString();
    }
  }

  private class InstructionSubjectFactory {

    InstructionSubject create(Instruction instruction) {
      if (isInvoke(instruction)) {
        return new InvokeInstructionSubject(this, instruction);
      } else if (isFieldAccess(instruction)) {
        return new FieldAccessInstructionSubject(this, instruction);
      } else {
        return new InstructionSubject(this, instruction);
      }
    }

    boolean isInvoke(Instruction instruction) {
      return isInvokeVirtual(instruction)
          || isInvokeInterface(instruction)
          || isInvokeDirect(instruction)
          || isInvokeSuper(instruction)
          || isInvokeStatic(instruction);
    }

    boolean isInvokeVirtual(Instruction instruction) {
      return instruction instanceof InvokeVirtual || instruction instanceof InvokeVirtualRange;
    }

    boolean isInvokeInterface(Instruction instruction) {
      return instruction instanceof InvokeInterface || instruction instanceof InvokeInterfaceRange;
    }

    boolean isInvokeDirect(Instruction instruction) {
      return instruction instanceof InvokeDirect || instruction instanceof InvokeDirectRange;
    }

    boolean isInvokeSuper(Instruction instruction) {
      return instruction instanceof InvokeSuper || instruction instanceof InvokeSuperRange;
    }

    boolean isInvokeStatic(Instruction instruction) {
      return instruction instanceof InvokeStatic || instruction instanceof InvokeStaticRange;
    }

    boolean isNop(Instruction instruction) {
      return instruction instanceof Nop;
    }

    boolean isGoto(Instruction instruction) {
      return instruction instanceof Goto;
    }

    boolean isReturnVoid(Instruction instruction) {
      return instruction instanceof ReturnVoid;
    }

    boolean isConst4(Instruction instruction) {
      return instruction instanceof Const4;
    }

    boolean isThrow(Instruction instruction) {
      return instruction instanceof Throw;
    }

    boolean isConstString(Instruction instruction) {
      return instruction instanceof ConstString;
    }

    boolean isConstString(Instruction instruction, String value) {
      return instruction instanceof ConstString
          && ((ConstString) instruction).BBBB.toSourceString().equals(value);
    }

    boolean isIfNez(Instruction instruction) {
      return instruction instanceof IfNez;
    }

    boolean isIfEqz(Instruction instruction) {
      return instruction instanceof IfEqz;
    }

    boolean isFieldAccess(Instruction instruction) {
      return isInstanceGet(instruction)
          || isInstancePut(instruction)
          || isStaticGet(instruction)
          || isStaticSet(instruction);
    }

    boolean isInstanceGet(Instruction instruction) {
      return instruction instanceof Iget
          || instruction instanceof IgetBoolean
          || instruction instanceof IgetByte
          || instruction instanceof IgetShort
          || instruction instanceof IgetChar
          || instruction instanceof IgetWide
          || instruction instanceof IgetObject;
    }

    boolean isInstancePut(Instruction instruction) {
      return instruction instanceof Iput
          || instruction instanceof IputBoolean
          || instruction instanceof IputByte
          || instruction instanceof IputShort
          || instruction instanceof IputChar
          || instruction instanceof IputWide
          || instruction instanceof IputObject;
    }

    boolean isStaticGet(Instruction instruction) {
      return instruction instanceof Sget
          || instruction instanceof SgetBoolean
          || instruction instanceof SgetByte
          || instruction instanceof SgetShort
          || instruction instanceof SgetChar
          || instruction instanceof SgetWide
          || instruction instanceof SgetObject;
    }

    boolean isStaticSet(Instruction instruction) {
      return instruction instanceof Sput
          || instruction instanceof SputBoolean
          || instruction instanceof SputByte
          || instruction instanceof SputShort
          || instruction instanceof SputChar
          || instruction instanceof SputWide
          || instruction instanceof SputObject;
    }
  }

  public class InstructionSubject {

    protected final InstructionSubjectFactory factory;
    protected final Instruction instruction;

    protected InstructionSubject(InstructionSubjectFactory factory, Instruction instruction) {
      this.factory = factory;
      this.instruction = instruction;
    }

    public boolean isInvoke() {
      return factory.isInvoke(instruction);
    }

    public boolean isFieldAccess() {
      return factory.isFieldAccess(instruction);
    }

    public boolean isInvokeVirtual() {
      return factory.isInvokeVirtual(instruction);
    }

    public boolean isInvokeInterface() {
      return factory.isInvokeInterface(instruction);
    }

    public boolean isInvokeDirect() {
      return factory.isInvokeDirect(instruction);
    }

    public boolean isInvokeSuper() {
      return factory.isInvokeSuper(instruction);
    }

    public boolean isInvokeStatic() {
      return factory.isInvokeStatic(instruction);
    }

    boolean isFieldAccess(Instruction instruction) {
      return factory.isFieldAccess(instruction);
    }

    public boolean isNop() {
      return factory.isNop(instruction);
    }

    public boolean isConstString() {
      return factory.isConstString(instruction);
    }

    public boolean isConstString(String value) {
      return factory.isConstString(instruction, value);
    }

    public boolean isGoto() {
      return factory.isGoto(instruction);
    }

    public boolean isIfNez() {
      return factory.isIfNez(instruction);
    }

    public boolean isIfEqz() {
      return factory.isIfEqz(instruction);
    }

    public boolean isReturnVoid() {
      return factory.isReturnVoid(instruction);
    }

    public boolean isConst4() {
      return factory.isConst4(instruction);
    }

    public boolean isThrow() {
      return factory.isThrow(instruction);
    }
  }

  public class InvokeInstructionSubject extends InstructionSubject {

    InvokeInstructionSubject(InstructionSubjectFactory factory, Instruction instruction) {
      super(factory, instruction);
      assert isInvoke();
    }

    public TypeSubject holder() {
      return new TypeSubject(invokedMethod().getHolder());
    }

    public DexMethod invokedMethod() {
      if (instruction instanceof InvokeVirtual) {
        return ((InvokeVirtual) instruction).getMethod();
      }
      if (instruction instanceof InvokeVirtualRange) {
        return ((InvokeVirtualRange) instruction).getMethod();
      }
      if (instruction instanceof InvokeInterface) {
        return ((InvokeInterface) instruction).getMethod();
      }
      if (instruction instanceof InvokeInterfaceRange) {
        return ((InvokeInterfaceRange) instruction).getMethod();
      }
      if (instruction instanceof InvokeDirect) {
        return ((InvokeDirect) instruction).getMethod();
      }
      if (instruction instanceof InvokeDirectRange) {
        return ((InvokeDirectRange) instruction).getMethod();
      }
      if (instruction instanceof InvokeSuper) {
        return ((InvokeSuper) instruction).getMethod();
      }
      if (instruction instanceof InvokeSuperRange) {
        return ((InvokeSuperRange) instruction).getMethod();
      }
      if (instruction instanceof InvokeDirect) {
        return ((InvokeDirect) instruction).getMethod();
      }
      if (instruction instanceof InvokeDirectRange) {
        return ((InvokeDirectRange) instruction).getMethod();
      }
      if (instruction instanceof InvokeStatic) {
        return ((InvokeStatic) instruction).getMethod();
      }
      if (instruction instanceof InvokeStaticRange) {
        return ((InvokeStaticRange) instruction).getMethod();
      }
      assert false;
      return null;
    }
  }

  public class FieldAccessInstructionSubject extends InstructionSubject {

    FieldAccessInstructionSubject(InstructionSubjectFactory factory, Instruction instruction) {
      super(factory, instruction);
      assert isFieldAccess();
    }

    public TypeSubject holder() {
      return new TypeSubject(accessedField().getHolder());
    }

    public DexField accessedField() {
      if (instruction instanceof Iget) {
        return ((Iget) instruction).getField();
      }
      if (instruction instanceof IgetBoolean) {
        return ((IgetBoolean) instruction).getField();
      }
      if (instruction instanceof IgetByte) {
        return ((IgetByte) instruction).getField();
      }
      if (instruction instanceof IgetShort) {
        return ((IgetShort) instruction).getField();
      }
      if (instruction instanceof IgetChar) {
        return ((IgetChar) instruction).getField();
      }
      if (instruction instanceof IgetWide) {
        return ((IgetWide) instruction).getField();
      }
      if (instruction instanceof IgetObject) {
        return ((IgetObject) instruction).getField();
      }
      if (instruction instanceof Iput) {
        return ((Iput) instruction).getField();
      }
      if (instruction instanceof IputBoolean) {
        return ((IputBoolean) instruction).getField();
      }
      if (instruction instanceof IputByte) {
        return ((IputByte) instruction).getField();
      }
      if (instruction instanceof IputShort) {
        return ((IputShort) instruction).getField();
      }
      if (instruction instanceof IputChar) {
        return ((IputChar) instruction).getField();
      }
      if (instruction instanceof IputWide) {
        return ((IputWide) instruction).getField();
      }
      if (instruction instanceof IputObject) {
        return ((IputObject) instruction).getField();
      }
      if (instruction instanceof Sget) {
        return ((Sget) instruction).getField();
      }
      if (instruction instanceof SgetBoolean) {
        return ((SgetBoolean) instruction).getField();
      }
      if (instruction instanceof SgetByte) {
        return ((SgetByte) instruction).getField();
      }
      if (instruction instanceof SgetShort) {
        return ((SgetShort) instruction).getField();
      }
      if (instruction instanceof SgetChar) {
        return ((SgetChar) instruction).getField();
      }
      if (instruction instanceof SgetWide) {
        return ((SgetWide) instruction).getField();
      }
      if (instruction instanceof SgetObject) {
        return ((SgetObject) instruction).getField();
      }
      if (instruction instanceof Sput) {
        return ((Sput) instruction).getField();
      }
      if (instruction instanceof SputBoolean) {
        return ((SputBoolean) instruction).getField();
      }
      if (instruction instanceof SputByte) {
        return ((SputByte) instruction).getField();
      }
      if (instruction instanceof SputShort) {
        return ((SputShort) instruction).getField();
      }
      if (instruction instanceof SputChar) {
        return ((SputChar) instruction).getField();
      }
      if (instruction instanceof SputWide) {
        return ((SputWide) instruction).getField();
      }
      if (instruction instanceof SputObject) {
        return ((SputObject) instruction).getField();
      }
      assert false;
      return null;
    }
  }

  private class InstructionIterator implements Iterator<InstructionSubject> {

    private final DexCode code;
    private int index;

    InstructionIterator(MethodSubject method) {
      assert method.isPresent();
      this.code = method.getMethod().getCode().asDexCode();
      this.index = 0;
    }

    @Override
    public boolean hasNext() {
      return index < code.instructions.length;
    }

    @Override
    public InstructionSubject next() {
      if (index == code.instructions.length) {
        throw new NoSuchElementException();
      }
      return factory.create(code.instructions[index++]);
    }
  }

  private class FilteredInstructionIterator<T extends InstructionSubject> implements Iterator<T> {

    private final InstructionIterator iterator;
    private final Predicate<InstructionSubject> predicate;
    private InstructionSubject pendingNext = null;

    FilteredInstructionIterator(MethodSubject method, Predicate<InstructionSubject> predicate) {
      this.iterator = new InstructionIterator(method);
      this.predicate = predicate;
      hasNext();
    }

    @Override
    public boolean hasNext() {
      if (pendingNext == null) {
        while (iterator.hasNext()) {
          pendingNext = iterator.next();
          if (predicate.test(pendingNext)) {
            break;
          }
          pendingNext = null;
        }
      }
      return pendingNext != null;
    }

    @Override
    public T next() {
      hasNext();
      if (pendingNext == null) {
        throw new NoSuchElementException();
      }
      // We cannot tell if the provided predicate will only match instruction subjects of type T.
      @SuppressWarnings("unchecked")
      T result = (T) pendingNext;
      pendingNext = null;
      return result;
    }
  }

  // Build the generic signature using the current mapping if any.
  class GenericSignatureGenerater implements GenericSignatureAction<String> {

    private StringBuilder signature;

    public String getSignature() {
      return signature.toString();
    }

    @Override
    public void parsedSymbol(char symbol) {
      signature.append(symbol);
    }

    @Override
    public void parsedIdentifier(String identifier) {
      signature.append(identifier);
    }

    @Override
    public String parsedTypeName(String name) {
      String type = name;
      if (originalToObfuscatedMapping != null) {
        String original = originalToObfuscatedMapping.inverse().get(name);
        type = original != null ? original : name;
      }
      signature.append(type);
      return type;
    }

    @Override
    public String parsedInnerTypeName(String enclosingType, String name) {
      String type;
      if (originalToObfuscatedMapping != null) {
        // The enclosingType has already been mapped if a mapping is present.
        String minifiedEnclosing = originalToObfuscatedMapping.get(enclosingType);
        type = originalToObfuscatedMapping.inverse().get(minifiedEnclosing + "$" + name);
        if (type != null) {
          assert type.startsWith(enclosingType + "$");
          name = type.substring(enclosingType.length() + 1);
        }
      } else {
        type = enclosingType + "$" + name;
      }
      signature.append(name);
      return type;
    }

    @Override
    public void start() {
      signature = new StringBuilder();
    }

    @Override
    public void stop() {
      // nothing to do
    }
  }
}
