// 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.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.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));
    }
  }

  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);
      return annotation == null
          ? new AbsentAnnotationSubject()
          : new FoundAnnotationSubject(annotation);
    }

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

    @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() {
      // 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) {
          if (originalToObfuscatedMapping != null) {
            // The enclosingType has already been mapped if a mapping is present.
            String minifiedEnclosing = originalToObfuscatedMapping.get(enclosingType);
            String type = originalToObfuscatedMapping.inverse().get(minifiedEnclosing + "$" + name);
            if (type != null) {
              assert type.startsWith(enclosingType + "$");
              name = type.substring(enclosingType.length() + 1);
            }
            signature.append(name);
            return type;
          } else {
            String type = enclosingType + "$" + name;
            signature.append(name);
            return type;
          }
        }

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

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

      String finalSignature = getFinalSignatureAttribute();
      if (finalSignature == null || mapping == null) {
        return finalSignature;
      }

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

    @Override
    public String getFinalSignatureAttribute() {
      DexAnnotation annotation = findAnnotation("dalvik.annotation.Signature");
      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();
    }

    @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 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;
    }
  }

  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 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 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;
    }
  }

  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 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;
    }
  }
}
