/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ahat.heapdump;

import com.android.ahat.progress.Progress;
import java.awt.image.BufferedImage;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.EnumMap;
import java.util.List;
import java.util.Queue;

/**
 * A Java instance from a parsed heap dump. It is the base class used for all
 * kinds of Java instances, including normal Java objects, class objects, and
 * arrays.
 */
public abstract class AhatInstance implements Diffable<AhatInstance> {
  // The id of this instance from the heap dump.
  private final long mId;

  // Fields initialized in initialize().
  private AhatHeap mHeap;
  private AhatClassObj mClassObj;
  private Site mSite;

  // Bit vector of the root types of this object.
  private int mRootTypes;

  // Field initialized via addRegisterednativeSize.
  private long mRegisteredNativeSize = 0;

  // Fields initialized in computeReachability().
  private Reachability mReachability = Reachability.UNREACHABLE;
  private AhatInstance mNextInstanceToGcRoot;
  private String mNextInstanceToGcRootField;
  private ArrayList<AhatInstance> mReverseReferences;

  // Fields initialized in DominatorsComputation.computeDominators().
  // mDominated - the list of instances immediately dominated by this instance.
  // mRetainedSizes - retained size indexed by heap index.
  private AhatInstance mImmediateDominator;
  private List<AhatInstance> mDominated = new ArrayList<AhatInstance>();
  private Size[] mRetainedSizes;

  // The baseline instance for purposes of diff.
  private AhatInstance mBaseline;

  // temporary user data associated with this instance. This is used for a
  // couple different purposes:
  // 1. During parsing of instances, to store temporary field data.
  // 2. During dominators computation, to store the dominators computation state.
  private Object mTemporaryUserData;

  AhatInstance(long id) {
    mId = id;
    mBaseline = this;
  }

  /**
   * Initialize this AhatInstance based on the the given info.
   */
  void initialize(AhatHeap heap, Site site, AhatClassObj classObj) {
    mHeap = heap;
    mSite = site;
    mClassObj = classObj;
  }

  /**
   * Returns a unique identifier for this instance.
   *
   * @return id of the instance
   */
  public long getId() {
    return mId;
  }

  /**
   * Returns the number of bytes used for this object in the heap.
   * The returned size is a shallow size for the object that does not include
   * sizes of other objects dominated by this object.
   *
   * @return the shallow size of the object
   */
  public Size getSize() {
    return new Size(mClassObj.getInstanceSize() + getExtraJavaSize(), mRegisteredNativeSize);
  }

  /**
   * Returns the number of bytes taken up by this object on the Java heap
   * beyond the standard instance size as recorded by the class of this
   * instance.
   *
   * For example, class objects will have extra size for static fields and
   * array objects will have extra size for the array elements.
   */
  abstract long getExtraJavaSize();

  /**
   * Returns the number of bytes retained by this object in the given heap.
   * The returned size includes the shallow size of this object and the size
   * of all objects directly or indirectly retained by this object. Only those
   * objects allocated on the given heap are included in the reported size.
   *
   * @param heap the heap to get the retained size for
   * @return the retained size of the object
   */
  public Size getRetainedSize(AhatHeap heap) {
    int index = heap.getIndex();
    if (mRetainedSizes != null && 0 <= index && index < mRetainedSizes.length) {
      return mRetainedSizes[heap.getIndex()];
    }
    return Size.ZERO;
  }

  /**
   * Returns the total number of bytes retained by this object. The returned
   * size includes the shallow size of this object and the size of all objects
   * directly or indirectly retained by this object.
   *
   * @return the total retained size of the object
   */
  public Size getTotalRetainedSize() {
    Size size = Size.ZERO;
    if (mRetainedSizes != null) {
      for (int i = 0; i < mRetainedSizes.length; i++) {
        size = size.plus(mRetainedSizes[i]);
      }
    }
    return size;
  }

  /**
   * Increment the number of registered native bytes tied to this object.
   */
  void addRegisteredNativeSize(long size) {
    mRegisteredNativeSize += size;
  }

  /**
   * Returns the reachability of the instance.
   *
   * @return the reachability of the instance.
   */
  public Reachability getReachability() {
    return mReachability;
  }

  /**
   * Returns true if this object is strongly reachable. An object is strongly
   * reachable if there exists a path of (strong) references from some root
   * object to this object.
   *
   * @return true if the object is strongly reachable
   */
  public boolean isStronglyReachable() {
    return mReachability == Reachability.STRONG;
  }

  /**
   * Returns true if this object is reachable only through a
   * soft/weak/phantom/finalizer reference. An object is weakly reachable if
   * it is not strongly reachable but there still exists a path of references
   * from some root object to this object.  Because the object is not strongly
   * reachable, any such path must contain a SoftReference, WeakReference,
   * PhantomReference, or FinalizerReference somewhere along it.
   * <p>
   * Unlike a strongly reachable object, a weakly reachable object is allowed
   * to be garbage collected.
   *
   * @deprecated Use {@link #getReachability()} instead, which can distinguish
   *             among soft, weak, phantom, and other kinds of references.
   *
   * @return true if the object is weakly reachable
   */
  @Deprecated public boolean isWeaklyReachable() {
    return !isStronglyReachable() && !isUnreachable();
  }

  /**
   * Returns true if this object is completely unreachable. An object is
   * completely unreachable if there is no path to the object from some root
   * object, neither through strong nor soft/weak/phantom/finalizer
   * references.
   *
   * @return true if the object is completely unreachable
   */
  public boolean isUnreachable() {
    return mReachability == Reachability.UNREACHABLE;
  }

  /**
   * Returns the heap that this instance is allocated on.
   *
   * @return heap the instance is allocated on
   */
  public AhatHeap getHeap() {
    return mHeap;
  }

  /**
   * Returns an iterator over the references this AhatInstance has to other
   * AhatInstances.
   */
  abstract Iterable<Reference> getReferences();

  /**
   * Returns true if this instance is a GC root.
   *
   * @return true if this instance is a GC root.
   */
  public boolean isRoot() {
    return mRootTypes != 0;
  }

  /**
   * Marks this instance as being a root of the given type.
   */
  void addRootType(RootType type) {
    mRootTypes |= type.mask;
  }

  /**
   * Returns a list of the root types of this object.
   * Returns null if this object is not a root.
   *
   * @return list of the objects root types
   */
  public Collection<RootType> getRootTypes() {
    if (!isRoot()) {
      return null;
    }

    List<RootType> types = new ArrayList<RootType>();
    for (RootType type : RootType.values()) {
      if ((mRootTypes & type.mask) != 0) {
        types.add(type);
      }
    }
    return types;
  }

  /**
   * Returns the immediate dominator of this instance.
   * Returns null if this is a root instance.
   *
   * @return the immediate dominator of this instance
   */
  public AhatInstance getImmediateDominator() {
    return mImmediateDominator;
  }

  /**
   * Returns a list of objects immediately dominated by this instance.
   *
   * @return list of immediately dominated objects
   */
  public List<AhatInstance> getDominated() {
    return mDominated;
  }

  /**
   * Returns the site where this instance was allocated.
   *
   * @return the object's allocation site
   */
  public Site getSite() {
    return mSite;
  }

  /**
   * Returns true if this instance is a class object
   *
   * @return true if this instance is a class object
   */
  public boolean isClassObj() {
    // Overridden by AhatClassObj.
    return false;
  }

  /**
   * Returns this as an AhatClassObj if this is an AhatClassObj.
   * Returns null if this is not an AhatClassObj.
   *
   * @return this instance as a class object
   */
  public AhatClassObj asClassObj() {
    // Overridden by AhatClassObj.
    return null;
  }

  /**
   * Returns the class object for this instance.
   * For example, if this object is an instance of java.lang.String, this
   * method returns the AhatClassObj for java.lang.String.
   *
   * @return the instance's class object
   */
  public AhatClassObj getClassObj() {
    return mClassObj;
  }

  /**
   * Returns the name of the class this object belongs to.
   * For example, if this object is an instance of java.lang.String, returns
   * "java.lang.String".
   *
   * @return the name of this instance's class
   */
  public String getClassName() {
    AhatClassObj classObj = getClassObj();
    return classObj == null ? "???" : classObj.getName();
  }

  /**
   * Returns true if this is an instance of a (subclass of a) class with the
   * given name.
   *
   * @param className the name of the class to check for
   * @return true if this is an instance of a (subclass of a) class with the
   *              given name
   */
  public boolean isInstanceOfClass(String className) {
    AhatClassObj cls = getClassObj();
    while (cls != null) {
      if (className.equals(cls.getName())) {
        return true;
      }
      cls = cls.getSuperClassObj();
    }
    return false;
  }

  /**
   * Returns true if the given instance is an array instance.
   *
   * @return true if the given instance is an array instance
   */
  public boolean isArrayInstance() {
    // Overridden by AhatArrayInstance.
    return false;
  }

  /**
   * Returns this as an AhatArrayInstance if this is an AhatArrayInstance.
   * Returns null if this is not an AhatArrayInstance.
   *
   * @return this instance as an array instance
   */
  public AhatArrayInstance asArrayInstance() {
    // Overridden by AhatArrayInstance.
    return null;
  }

  /**
   * Returns true if this instance is a class instance.
   *
   * @return true if this instance is a class instance
   */
  public boolean isClassInstance() {
    return false;
  }

  /**
   * Returns this as an AhatClassInstance if this is an AhatClassInstance.
   * Returns null if this is not an AhatClassInstance.
   *
   * @return this instance as a class instance
   */
  public AhatClassInstance asClassInstance() {
    return null;
  }

  /**
   * Returns the <code>referent</code> associated with this instance.
   * This is only relevant for instances of java.lang.ref.Reference or its
   * subclasses. Returns null if the instance has no referent associated with
   * it.
   *
   * @return the referent associated with this instance
   */
  public AhatInstance getReferent() {
    // Overridden by AhatClassInstance.
    return null;
  }

  /**
   * Returns a list of objects with any kind of reference to this object.
   *
   * @return the objects referencing this object
   */
  public List<AhatInstance> getReverseReferences() {
    if (mReverseReferences != null) {
      return mReverseReferences;
    }
    return Collections.emptyList();
  }

  /**
   * Returns a list of objects with (strong) references to this object.
   *
   * @deprecated Use {@link #getReverseReferences()} instead.
   *
   * @return the objects referencing this object
   */
  @Deprecated public List<AhatInstance> getHardReverseReferences() {
    List<AhatInstance> refs = new ArrayList<AhatInstance>();
    for (AhatInstance ref : getReverseReferences()) {
      if (ref.getReachability() == Reachability.STRONG && ref.getReferent() != this) {
        refs.add(ref);
      }
    }
    return refs;
  }

  /**
   * Returns a list of objects with soft/weak/phantom/finalizer references to
   * this object.
   *
   * @deprecated Use {@link #getReverseReferences()} instead.
   *
   * @return the objects weakly referencing this object
   */
  @Deprecated public List<AhatInstance> getSoftReverseReferences() {
    List<AhatInstance> refs = new ArrayList<AhatInstance>();
    for (AhatInstance ref : getReverseReferences()) {
      if (ref.getReachability() != Reachability.STRONG || ref.getReferent() == this) {
        refs.add(ref);
      }
    }
    return refs;
  }

  /**
   * Returns the value of a field of this instance. Returns null if the field
   * value is null, the field couldn't be read, or there are multiple fields
   * with the same name.
   *
   * @param fieldName the name of the field to get the value of
   * @return the field value
   */
  public Value getField(String fieldName) {
    // Overridden by AhatClassInstance.
    return null;
  }

  /**
   * Reads a reference field of this instance. Returns null if the field value
   * is null, of primitive type, or if the field couldn't be read. There is no
   * way using this method to distinguish between a reference field with value
   * <code>null</code> and an invalid field.
   *
   * @param fieldName the name of the reference field to get the value of
   * @return the reference field value
   */
  public AhatInstance getRefField(String fieldName) {
    // Overridden by AhatClassInstance.
    return null;
  }

  /**
   * Returns the dex location associated with this object. Only applies to
   * instances of dalvik.system.DexCache. If this is an instance of DexCache,
   * returns the dex location for that dex cache. Otherwise returns null.
   * If maxChars is non-negative, the returned location is truncated to
   * maxChars in length.
   *
   * @param maxChars the maximum length of the returned string
   * @return the dex location associated with this object
   */
  public String getDexCacheLocation(int maxChars) {
    return null;
  }

  /**
   * Returns the name of the Binder proxy interface associated with this object.
   * Only applies to instances of android.os.BinderProxy. If this is an
   * instance of BinderProxy, returns the fully qualified binder interface name,
   * otherwise returns null.
   *
   * @return the name of the binder interface associated with this object
   */
  public String getBinderProxyInterfaceName() {
    return null;
  }

  /**
   * Returns the descriptor of the Binder token associated with this object.
   * Only applies to instances of android.os.Binder. If this is an instance of
   * android.os.Binder with a subclass of the name "descriptor$Stub", the
   * object in question is a binder stub, and this function will return null.
   * In that case, @see AhatInstance#getBinderStubInterfaceName
   *
   * @return the descriptor of this object, if it's a binder token
   */
  public String getBinderTokenDescriptor() {
    return null;
  }

  /**
   * Returns the name of the Binder stub interface associated with this object.
   * Only applies to instances which are a subclass of android.os.Binder,
   * and are an instance of class 'descriptor$Stub', where descriptor
   * is the descriptor of the android.os.Binder object.
   *
   * @return the name of the binder interface associated with this object,
   *         or null if this is not a binder stub interface.
   */
  public String getBinderStubInterfaceName() {
    return null;
  }

  /**
   * Returns the android.graphics.Bitmap instance associated with this object.
   * Instances of android.graphics.Bitmap return themselves. If this is a
   * byte[] array containing pixel data for an instance of
   * android.graphics.Bitmap, that instance of android.graphics.Bitmap is
   * returned. Otherwise null is returned.
   *
   * @return the bitmap instance associated with this object
   */
  public AhatInstance getAssociatedBitmapInstance() {
    return null;
  }

  /**
   * Returns the class object that this object represents the overhead for.
   * ART adds a fake byte[] $classOverhead static field to classes to show the
   * overheads associated with the class. If this is one such byte[] instance,
   * returns the class it is associated with. Otherwise null is returned.
   *
   * @return the class instance that this is the overhead for
   */
  public AhatClassObj getAssociatedClassForOverhead() {
    return null;
  }

  /**
   * Returns the (bounded-length) string associated with this instance.
   * Applies to instances of java.lang.String, char[], and in some cases
   * byte[]. Returns null if this object cannot be interpreted as a string.
   * If maxChars is non-negative, the returned string is truncated to maxChars
   * characters in length.
   *
   * @param maxChars the maximum length of the returned string
   * @return the string associated with this instance
   */
  public String asString(int maxChars) {
    // By default instances can't be interpreted as a string. This method is
    // overridden by AhatClassInstance and AhatArrayInstance for those cases
    // when an instance can be interpreted as a string.
    return null;
  }

  /**
   * Returns the string associated with this instance. Applies to instances of
   * java.lang.String, char[], and in some cases byte[]. Returns null if this
   * object cannot be interpreted as a string.
   *
   * @return the string associated with this instance
   */
  public String asString() {
    return asString(-1);
  }

  /**
   * Returns the bitmap pixel data associated with this instance.
   * This is relevant for instances of android.graphics.Bitmap and byte[].
   * Returns null if there is no bitmap pixel data associated with the given
   * instance.
   *
   * @return the bitmap pixel data associated with this image
   */
  public BufferedImage asBitmap() {
    return null;
  }

  static class RegisteredNativeAllocation {
    public AhatInstance referent;
    public long size;
  };

  /**
   * Return the registered native allocation that this instance represents, if
   * any. This is relevant for instances of sun.misc.Cleaner.
   */
  RegisteredNativeAllocation asRegisteredNativeAllocation() {
    return null;
  }

  /**
   * Returns a sample path from a GC root to this instance. The first element
   * of the returned path is a GC root object. This instance is included as
   * the last element of the path with an empty field description.
   * <p>
   * If the instance is strongly reachable, a path of string references will
   * be returned. If the instance is weakly reachable, the returned path will
   * include a soft/weak/phantom/finalizer reference somewhere along it.
   * Returns null if this instance is not reachable.
   *
   * @return sample path from a GC root to this instance
   * @see PathElement
   */
  public List<PathElement> getPathFromGcRoot() {
    if (isUnreachable()) {
      return null;
    }

    List<PathElement> path = new ArrayList<PathElement>();

    AhatInstance dom = this;
    for (PathElement elem = new PathElement(this, ""); elem != null;
        elem = getNextPathElementToGcRoot(elem.instance)) {
      if (elem.instance.equals(dom)) {
        elem.isDominator = true;
        dom = dom.getImmediateDominator();
      }
      path.add(elem);
    }
    Collections.reverse(path);
    return path;
  }

  /**
   * Returns the next instance to GC root from this object and a string
   * description of which field of that object refers to the given instance.
   * Returns null if the given instance has no next instance to the gc root.
   */
  private static PathElement getNextPathElementToGcRoot(AhatInstance inst) {
    if (inst.isRoot()) {
      return null;
    }
    return new PathElement(inst.mNextInstanceToGcRoot, inst.mNextInstanceToGcRootField);
  }

  /**
   * Returns a human-readable identifier for this object.
   * For class objects, the string is the class name.
   * For class instances, the string is the class name followed by '@' and the
   * hex id of the instance.
   * For array instances, the string is the array type followed by the size in
   * square brackets, followed by '@' and the hex id of the instance.
   *
   * @return human-readable identifier for this object
   */
  @Override public abstract String toString();

  /**
   * Read the byte[] value from an hprof Instance.
   * Returns null if the instance is not a byte array.
   */
  byte[] asByteArray() {
    return null;
  }

  void setBaseline(AhatInstance baseline) {
    mBaseline = baseline;
  }

  @Override public AhatInstance getBaseline() {
    return mBaseline;
  }

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

  /**
   * Returns a new place holder instance corresponding to this instance.
   */
  AhatInstance newPlaceHolderInstance() {
    return new AhatPlaceHolderInstance(this);
  }

  void setTemporaryUserData(Object state) {
    mTemporaryUserData = state;
  }

  Object getTemporaryUserData() {
    return mTemporaryUserData;
  }

  /**
   * Determine the reachability of the all instances reachable from the given
   * root instance. Initializes the following fields:
   *   mReachability
   *   mNextInstanceToGcRoot
   *   mNextInstanceToGcRootField
   *   mReverseReferences
   *
   * @param progress used to track progress of the traversal.
   * @param numInsts upper bound on the total number of instances reachable
   *                 from the root, solely used for the purposes of tracking
   *                 progress.
   */
  static void computeReachability(SuperRoot root, Progress progress, long numInsts) {
    // Start by doing a breadth first search through strong references.
    // Then continue the breadth first through each weaker kind of reference.
    progress.start("Computing reachability", numInsts);
    EnumMap<Reachability, Queue<Reference>> queues = new EnumMap<>(Reachability.class);
    for (Reachability reachability : Reachability.values()) {
      queues.put(reachability, new ArrayDeque<Reference>());
    }

    for (Reference ref : root.getReferences()) {
      queues.get(Reachability.STRONG).add(ref);
    }

    for (Reachability reachability : Reachability.values()) {
      Queue<Reference> queue = queues.get(reachability);
      while (!queue.isEmpty()) {
        Reference ref = queue.poll();
        if (ref.ref.mReachability == Reachability.UNREACHABLE) {
          // This is the first time we have seen ref.ref.
          progress.advance();
          ref.ref.mReachability = reachability;
          ref.ref.mNextInstanceToGcRoot = ref.src;
          ref.ref.mNextInstanceToGcRootField = ref.field;
          ref.ref.mReverseReferences = new ArrayList<AhatInstance>();

          for (Reference childRef : ref.ref.getReferences()) {
            if (childRef.reachability.notWeakerThan(reachability)) {
              queue.add(childRef);
            } else {
              queues.get(childRef.reachability).add(childRef);
            }
          }
        }

        // Note: We specifically exclude 'root' from the reverse references
        // because it is a fake SuperRoot instance not present in the original
        // heap dump.
        if (ref.src != root) {
          ref.ref.mReverseReferences.add(ref.src);
        }
      }
    }
    progress.done();
  }

  /**
   * Recursively compute the retained size of the given instance and all
   * other instances it dominates.
   */
  static void computeRetainedSize(AhatInstance inst, int numHeaps) {
    // Note: We can't use a recursive implementation because it can lead to
    // stack overflow. Use an iterative implementation instead.
    //
    // Objects not yet processed will have mRetainedSizes set to null.
    // Once prepared, an object will have mRetaiedSizes set to an array of 0
    // sizes.
    Deque<AhatInstance> deque = new ArrayDeque<AhatInstance>();
    deque.push(inst);

    while (!deque.isEmpty()) {
      inst = deque.pop();
      if (inst.mRetainedSizes == null) {
        inst.mRetainedSizes = new Size[numHeaps];
        for (int i = 0; i < numHeaps; i++) {
          inst.mRetainedSizes[i] = Size.ZERO;
        }
        if (!(inst instanceof SuperRoot)) {
          inst.mRetainedSizes[inst.mHeap.getIndex()] =
            inst.mRetainedSizes[inst.mHeap.getIndex()].plus(inst.getSize());
        }
        deque.push(inst);
        for (AhatInstance dominated : inst.mDominated) {
          deque.push(dominated);
        }
      } else {
        for (AhatInstance dominated : inst.mDominated) {
          for (int i = 0; i < numHeaps; i++) {
            inst.mRetainedSizes[i] = inst.mRetainedSizes[i].plus(dominated.mRetainedSizes[i]);
          }
        }
      }
    }
  }

  Iterable<AhatInstance> getReferencesForDominators(Reachability retained) {
    return new DominatorReferenceIterator(retained, getReferences());
  }

  void setDominator(AhatInstance dominator) {
    mImmediateDominator = dominator;
    mImmediateDominator.mDominated.add(this);
  }
}
