/*
 * Copyright (C) 2015 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.tools.perflib.heap.StackFrame;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Site implements Diffable<Site> {
  // The site that this site was directly called from.
  // mParent is null for the root site.
  private Site mParent;

  private String mMethodName;
  private String mSignature;
  private String mFilename;
  private int mLineNumber;

  // To identify this site, we pick a stack trace that includes the site.
  // mId is the id of an object allocated at that stack trace, and mDepth
  // is the number of calls between this site and the innermost site of
  // allocation of the object with mId.
  // For the root site, mId is 0 and mDepth is 0.
  private long mId;
  private int mDepth;

  // The total size of objects allocated in this site (including child sites),
  // organized by heap index. Heap indices outside the range of mSizesByHeap
  // implicitly have size 0.
  private Size[] mSizesByHeap;

  // List of child sites.
  private List<Site> mChildren;

  // List of all objects allocated in this site (including child sites).
  private List<AhatInstance> mObjects;
  private List<ObjectsInfo> mObjectsInfos;
  private Map<AhatHeap, Map<AhatClassObj, ObjectsInfo>> mObjectsInfoMap;

  private Site mBaseline;

  public static class ObjectsInfo implements Diffable<ObjectsInfo> {
    public AhatHeap heap;
    public AhatClassObj classObj;   // May be null.
    public long numInstances;
    public Size numBytes;
    private ObjectsInfo baseline;

    /**
     * Construct a new, empty objects info for the given heap and class
     * combination.
     */
    public ObjectsInfo(AhatHeap heap, AhatClassObj classObj) {
      this.heap = heap;
      this.classObj = classObj;
      this.numInstances = 0;
      this.numBytes = Size.ZERO;
      this.baseline = this;
    }

    /**
     * Returns the name of the class this ObjectsInfo is associated with.
     */
    public String getClassName() {
      return classObj == null ? "???" : classObj.getName();
    }

    public void setBaseline(ObjectsInfo baseline) {
      this.baseline = baseline;
    }

    @Override public ObjectsInfo getBaseline() {
      return baseline;
    }

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

  /**
   * Construct a root site.
   */
  public Site(String name) {
    this(null, name, "", "", 0, 0, 0);
  }

  public Site(Site parent, String method, String signature, String file,
      int line, long id, int depth) {
    mParent = parent;
    mMethodName = method;
    mSignature = signature;
    mFilename = file;
    mLineNumber = line;
    mId = id;
    mDepth = depth;
    mSizesByHeap = new Size[0];
    mChildren = new ArrayList<Site>();
    mObjects = new ArrayList<AhatInstance>();
    mObjectsInfos = new ArrayList<ObjectsInfo>();
    mObjectsInfoMap = new HashMap<AhatHeap, Map<AhatClassObj, ObjectsInfo>>();
    mBaseline = this;
  }

  /**
   * Add an instance to this site.
   * Returns the site at which the instance was allocated.
   * @param frames - The list of frames in the stack trace, starting with the inner-most frame.
   * @param depth - The number of frames remaining before the inner-most frame is reached.
   */
  Site add(StackFrame[] frames, int depth, AhatInstance inst) {
    return add(this, frames, depth, inst);
  }

  private static Site add(Site site, StackFrame[] frames, int depth, AhatInstance inst) {
    while (true) {
      site.mObjects.add(inst);

      ObjectsInfo info = site.getObjectsInfo(inst.getHeap(), inst.getClassObj());
      if (inst.isReachable()) {
        AhatHeap heap = inst.getHeap();
        if (heap.getIndex() >= site.mSizesByHeap.length) {
          Size[] newSizes = new Size[heap.getIndex() + 1];
          for (int i = 0; i < site.mSizesByHeap.length; i++) {
            newSizes[i] = site.mSizesByHeap[i];
          }
          for (int i = site.mSizesByHeap.length; i < heap.getIndex() + 1; i++) {
            newSizes[i] = Size.ZERO;
          }
          site.mSizesByHeap = newSizes;
        }
        site.mSizesByHeap[heap.getIndex()]
          = site.mSizesByHeap[heap.getIndex()].plus(inst.getSize());

        info.numInstances++;
        info.numBytes = info.numBytes.plus(inst.getSize());
      }

      if (depth > 0) {
        StackFrame next = frames[depth - 1];
        Site child = null;
        for (int i = 0; i < site.mChildren.size(); i++) {
          Site curr = site.mChildren.get(i);
          if (curr.mLineNumber == next.getLineNumber()
              && curr.mMethodName.equals(next.getMethodName())
              && curr.mSignature.equals(next.getSignature())
              && curr.mFilename.equals(next.getFilename())) {
            child = curr;
            break;
          }
        }
        if (child == null) {
          child = new Site(site, next.getMethodName(), next.getSignature(),
              next.getFilename(), next.getLineNumber(), inst.getId(), depth - 1);
          site.mChildren.add(child);
        }
        depth = depth - 1;
        site = child;
      } else {
        return site;
      }
    }
  }

  // Get the size of a site for a specific heap.
  public Size getSize(AhatHeap heap) {
    int index = heap.getIndex();
    return index >= 0 && index < mSizesByHeap.length ? mSizesByHeap[index] : Size.ZERO;
  }

  /**
   * Get the list of objects allocated under this site. Includes objects
   * allocated in children sites.
   */
  public Collection<AhatInstance> getObjects() {
    return mObjects;
  }

  /**
   * Returns the ObjectsInfo at this site for the given heap and class
   * objects. Creates a new empty ObjectsInfo if none existed before.
   */
  ObjectsInfo getObjectsInfo(AhatHeap heap, AhatClassObj classObj) {
    Map<AhatClassObj, ObjectsInfo> classToObjectsInfo = mObjectsInfoMap.get(heap);
    if (classToObjectsInfo == null) {
      classToObjectsInfo = new HashMap<AhatClassObj, ObjectsInfo>();
      mObjectsInfoMap.put(heap, classToObjectsInfo);
    }

    ObjectsInfo info = classToObjectsInfo.get(classObj);
    if (info == null) {
      info = new ObjectsInfo(heap, classObj);
      mObjectsInfos.add(info);
      classToObjectsInfo.put(classObj, info);
    }
    return info;
  }

  public List<ObjectsInfo> getObjectsInfos() {
    return mObjectsInfos;
  }

  // Get the combined size of the site for all heaps.
  public Size getTotalSize() {
    Size total = Size.ZERO;
    for (int i = 0; i < mSizesByHeap.length; i++) {
      total = total.plus(mSizesByHeap[i]);
    }
    return total;
  }

  /**
   * Return the site this site was called from.
   * Returns null for the root site.
   */
  public Site getParent() {
    return mParent;
  }

  public String getMethodName() {
    return mMethodName;
  }

  public String getSignature() {
    return mSignature;
  }

  public String getFilename() {
    return mFilename;
  }

  public int getLineNumber() {
    return mLineNumber;
  }

  /**
   * Returns the id of some object allocated in this site.
   */
  public long getId() {
    return mId;
  }

  /**
   * Returns the number of frames between this site and the site where the
   * object with id getId() was allocated.
   */
  public int getDepth() {
    return mDepth;
  }

  public List<Site> getChildren() {
    return mChildren;
  }

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

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

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

  /**
   * Adds a place holder instance to this site and all parent sites.
   */
  void addPlaceHolderInstance(AhatInstance placeholder) {
    for (Site site = this; site != null; site = site.mParent) {
      site.mObjects.add(placeholder);
    }
  }
}
