/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.internal.size;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.apache.geode.annotations.Immutable;
import org.apache.geode.internal.Assert;
import org.apache.geode.internal.JvmSizeUtils;
import org.apache.geode.pdx.internal.unsafe.UnsafeWrapper;

/**
 * Figure out the size of an object using reflection. This class does not follow any object
 * references, it just calculates the size of a flat object.
 *
 *
 */
public class ReflectionSingleObjectSizer implements SingleObjectSizer {
  public static final int REFERENCE_SIZE = JvmSizeUtils.getReferenceSize();
  public static final int OBJECT_SIZE = JvmSizeUtils.getObjectHeaderSize();

  @Immutable
  private static final UnsafeWrapper unsafe;
  static {
    UnsafeWrapper tmp = null;
    try {
      tmp = new UnsafeWrapper();
    } catch (RuntimeException ignore) {
    } catch (Error ignore) {
    }
    unsafe = tmp;
  }

  @Override
  public long sizeof(Object object) {
    return sizeof(object, true);
  }

  public long sizeof(Object object, boolean roundResult) {
    Class<?> clazz = object.getClass();
    long size;
    if (clazz.isArray()) {
      if (unsafe != null) {
        size = unsafe.arrayBaseOffset(clazz);
        int arrayLength = Array.getLength(object);
        if (arrayLength > 0) {
          int typeSize = unsafe.arrayScaleIndex(clazz);
          if (typeSize == 0) {
            // the javadocs say that arrayScaleIndex may return 0.
            // If it did then we use sizeType.
            typeSize = sizeType(clazz.getComponentType());
          }
          size += (long) arrayLength * typeSize;
        }
      } else {
        // not as accurate but does not use unsafe
        size = OBJECT_SIZE + 4 /* for array length */;
        int arrayLength = Array.getLength(object);
        if (arrayLength > 0) {
          size += (long) arrayLength * sizeType(clazz.getComponentType());
        }
      }
      if (roundResult) {
        size = roundUpSize(size);
      }
      return size;
    } else {
      return sizeof(clazz, roundResult);
    }
  }

  public static long sizeof(Class clazz) {
    return sizeof(clazz, true);
  }

  /**
   * Since unsafe.fieldOffset(Field) will give us the offset to the first byte of that field all we
   * need to do is find which of the non-static declared fields has the greatest offset.
   */
  public static long sizeof(Class clazz, boolean roundResult) {
    Assert.assertTrue(!clazz.isArray());
    long size;
    if (unsafe != null) {
      Field lastField = null;
      long lastFieldOffset = 0;
      do {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
          if (!Modifier.isStatic(field.getModifiers())) {
            long offset = unsafe.fieldOffset(field);
            if (offset >= lastFieldOffset) {
              lastFieldOffset = offset;
              lastField = field;
            }
          }
        }
        if (lastField != null) {
          // if we have found a field in a subclass then one of them will be the last field
          // so just break without looking at super class fields.
          break;
        }
        clazz = clazz.getSuperclass();
      } while (clazz != null);

      if (lastField != null) {
        size = lastFieldOffset + sizeType(lastField.getType());
      } else {
        // class with no fields
        size = OBJECT_SIZE;
      }
    } else {
      // This code is not as accurate as unsafe but gives an estimate of memory used.
      // If it is wrong it will always under estimate because it does not account
      // for any of the field alignment that the jvm does.
      size = OBJECT_SIZE;
      do {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
          if (!Modifier.isStatic(field.getModifiers())) {
            size += sizeType(field.getType());
          }
        }
        clazz = clazz.getSuperclass();
      } while (clazz != null);
    }
    if (roundResult) {
      size = roundUpSize(size);
    }
    return size;
  }

  public static long roundUpSize(long size) {
    // Round up to the nearest 8 bytes. Experimentally, this
    // is what we've seen the sun 32 bit VM do with object size.
    // See https://wiki.gemstone.com/display/rusage/Per+Entry+Overhead
    long remainder = size % 8;
    if (remainder != 0) {
      size = size - remainder + 8;
    }
    return size;
  }

  private static int sizeType(Class<?> t) {

    if (t == Boolean.TYPE)
      return 1;
    else if (t == Byte.TYPE)
      return 1;
    else if (t == Character.TYPE)
      return 2;
    else if (t == Short.TYPE)
      return 2;
    else if (t == Integer.TYPE)
      return 4;
    else if (t == Long.TYPE)
      return 8;
    else if (t == Float.TYPE)
      return 4;
    else if (t == Double.TYPE)
      return 8;
    else if (t == Void.TYPE)
      return 0;
    else
      return REFERENCE_SIZE;
  }


}
