/*
 * 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.
 */

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import libcore.util.NativeAllocationRegistry;

// We take a heap dump that includes a single instance of this
// DumpedStuff class. Objects stored as fields in this class can be easily
// found in the hprof dump by searching for the instance of the DumpedStuff
// class and reading the desired field.
public class DumpedStuff extends SuperDumpedStuff {
  private void allocateObjectAtKnownSite() {
    objectAllocatedAtKnownSite = new Object();
    allocateObjectAtKnownSubSite();
    allocateObjectAtObfSuperSite();
    allocateObjectAtUnObfSuperSite();
    allocateObjectAtOverriddenSite();
  }

  private void allocateObjectAtKnownSubSite() {
    objectAllocatedAtKnownSubSite = new Object();
  }

  public void allocateObjectAtOverriddenSite() {
    objectAllocatedAtOverriddenSite = new Object();
  }

  DumpedStuff(boolean baseline) {
    allocateObjectAtKnownSite();

    int n = baseline ? 400000 : 1000000;
    bigArray = new byte[n];
    for (int i = 0; i < n; i++) {
      bigArray[i] = (byte)((i * i) & 0xFF);
    }

    // 0x12345, 50000, and 0xABCDABCD are arbitrary values.
    NativeAllocationRegistry registry = new NativeAllocationRegistry(
        Main.class.getClassLoader(), 0x12345, 50000);
    registry.registerNativeAllocation(anObject, 0xABCDABCD);

    {
      Object object = new Object();
      aLongStrongPathToSamplePathObject = new Reference(new Reference(new Reference(object)));
      aShortWeakPathToSamplePathObject = new WeakReference(new Reference(object));
    }

    addedObject = baseline ? null : new AddedObject();
    removedObject = baseline ? new RemovedObject() : null;
    modifiedObject = new ModifiedObject();
    modifiedObject.value = baseline ? 5 : 8;
    modifiedObject.modifiedRefField = baseline ? "A1" : "A2";
    modifiedObject.unmodifiedRefField = "B";
    modifiedStaticField = baseline ? "C1" : "C2";
    modifiedArray = baseline ? new int[]{0, 1, 2, 3} : new int[]{3, 1, 2, 0};

    // Deep matching dominator trees shouldn't smash the stack when we try
    // to diff them. Make some deep dominator trees to help test it.
    for (int i = 0; i < 10000; i++) {
      StackSmasher smasher = new StackSmasher();
      smasher.child = stackSmasher;
      stackSmasher = smasher;

      if (!baseline) {
        smasher = new StackSmasher();
        smasher.child = stackSmasherAdded;
        stackSmasherAdded = smasher;
      }
    }

    gcPathArray[2].right.left = gcPathArray[2].left.right;
  }

  public static class ObjectTree {
    public ObjectTree left;
    public ObjectTree right;

    public ObjectTree(ObjectTree left, ObjectTree right) {
      this.left = left;
      this.right = right;
    }
  }

  public static class AddedObject {
  }

  public static class RemovedObject {
  }

  public static class UnchangedObject {
  }

  public static class ModifiedObject {
    public int value;
    public String modifiedRefField;
    public String unmodifiedRefField;
  }

  public static class StackSmasher {
    public StackSmasher child;
  }

  public static class Reference {
    public Object referent;

    public Reference(Object referent) {
      this.referent = referent;
    }
  }

  public interface IDumpedManager {
    public static class Stub extends android.os.Binder implements IDumpedManager {
      private static final java.lang.String DESCRIPTOR = "DumpedStuff$IDumpedManager";
      public Stub() {
        super(DESCRIPTOR);
      }
      public static class Proxy implements IDumpedManager {
        android.os.IBinder mRemote;
        Proxy(android.os.IBinder binderProxy) {
          mRemote = binderProxy;
        }
      }
    }
  }

  public interface IBinderInterfaceImpostor {
    public static class Stub {
      public static class Proxy implements IBinderInterfaceImpostor {
        android.os.IBinder mFakeRemote = new android.os.BinderProxy();
        Proxy(android.os.IBinder binderProxy) {
          mFakeRemote = binderProxy;
        }
      }
    }
  }

  private static class BinderProxyCarrier {
    android.os.IBinder mRemote;
    BinderProxyCarrier(android.os.IBinder binderProxy) {
      mRemote = binderProxy;
    }
  }

  private static class BinderService extends IDumpedManager.Stub {
    // Intentionally empty
  };

  private static class FakeBinderService extends IBinderInterfaceImpostor.Stub {
    // Intentionally empty
  };

  public String basicString = "hello, world";
  public String nonAscii = "Sigma (Ʃ) is not ASCII";
  public String embeddedZero = "embedded\0...";  // Non-ASCII for string compression purposes.
  public char[] charArray = "char thing".toCharArray();
  public String nullString = null;
  public Object anObject = new Object();
  public Reference aReference = new Reference(anObject);
  public ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
  public PhantomReference aPhantomReference = new PhantomReference(anObject, referenceQueue);
  public WeakReference aWeakReference = new WeakReference(anObject, referenceQueue);
  public WeakReference aNullReferentReference = new WeakReference(null, referenceQueue);
  public SoftReference aSoftReference = new SoftReference(new Object());
  public Reference reachabilityReferenceChain;
  public byte[] bigArray;
  public ObjectTree[] gcPathArray = new ObjectTree[]{null, null,
    new ObjectTree(
        new ObjectTree(null, new ObjectTree(null, null)),
        new ObjectTree(null, null)),
    null};
  public Reference aLongStrongPathToSamplePathObject;
  public WeakReference aShortWeakPathToSamplePathObject;
  public WeakReference aWeakRefToGcRoot = new WeakReference(Main.class);
  public SoftReference aSoftChain = new SoftReference(new Reference(new Reference(new Object())));
  public Object[] basicStringRef;
  public AddedObject addedObject;
  public UnchangedObject unchangedObject = new UnchangedObject();
  public RemovedObject removedObject;
  public ModifiedObject modifiedObject;
  public StackSmasher stackSmasher;
  public StackSmasher stackSmasherAdded;
  public static String modifiedStaticField;
  public int[] modifiedArray;
  public Object objectAllocatedAtKnownSite;
  public Object objectAllocatedAtKnownSubSite;
  public android.os.IBinder correctBinderProxy = new android.os.BinderProxy();
  public android.os.IBinder imposedBinderProxy = new android.os.BinderProxy();
  public android.os.IBinder carriedBinderProxy = new android.os.BinderProxy();
  Object correctBinderProxyObject = new IDumpedManager.Stub.Proxy(correctBinderProxy);
  Object impostorBinderProxyObject = new IBinderInterfaceImpostor.Stub.Proxy(imposedBinderProxy);
  Object carrierBinderProxyObject = new BinderProxyCarrier(carriedBinderProxy);

  Object binderService = new BinderService();
  Object fakeBinderService = new FakeBinderService();
  Object binderToken = new android.os.Binder();
  Object namedBinderToken = new android.os.Binder("awesomeToken");

  // Allocate those objects that we need to not be GC'd before taking the heap
  // dump.
  public void shouldNotGc() {
    reachabilityReferenceChain = new Reference(
        new SoftReference(
        new Reference(
        new WeakReference(
        new SoftReference(
        new PhantomReference(new Object(), referenceQueue))))));
  }
}
