/**
 * Copyright The Apache Software Foundation
 *
 * 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.tajo.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;

/**
 * Class for determining the "size" of a class, an attempt to calculate the
 * actual bytes that an object of this class will occupy in memory
 *
 * The core of this class is taken from the Derby project
 */

public class ClassSize {
  static final Log LOG = LogFactory.getLog(ClassSize.class);

  private static int nrOfRefsPerObj = 2;

  /** Array overhead */
  public static final int ARRAY;

  /** Overhead for ArrayList(0) */
  public static final int ARRAYLIST;

  /** Overhead for ByteBuffer */
  public static final int BYTE_BUFFER;

  /** Overhead for an Short */
  public static final int SHORT;

  /** Overhead for an Integer */
  public static final int INTEGER;

  /** Overhead for an Long */
  public static final int LONG;

  /** Overhead for an Float */
  public static final int FLOAT;

  /** Overhead for an Double */
  public static final int DOUBLE;

  /** Overhead for entry in map */
  public static final int MAP_ENTRY;

  /** Object overhead is minimum 2 * reference size (8 bytes on 64-bit) */
  public static final int OBJECT;

  /** Reference size is 8 bytes on 64-bit, 4 bytes on 32-bit */
  public static final int REFERENCE;

  /** String overhead */
  public static final int STRING;

  /** Overhead for TreeMap */
  public static final int TREEMAP;

  /** Overhead for ConcurrentHashMap */
  public static final int CONCURRENT_HASHMAP;

  /** Overhead for ConcurrentHashMap.Entry */
  public static final int CONCURRENT_HASHMAP_ENTRY;

  /** Overhead for ConcurrentHashMap.Segment */
  public static final int CONCURRENT_HASHMAP_SEGMENT;

  /** Overhead for ConcurrentSkipListMap */
  public static final int CONCURRENT_SKIPLISTMAP;

  /** Overhead for ConcurrentSkipListMap Entry */
  public static final int CONCURRENT_SKIPLISTMAP_ENTRY;

  /** Overhead for ReentrantReadWriteLock */
  public static final int REENTRANT_LOCK;

  /** Overhead for AtomicLong */
  public static final int ATOMIC_LONG;

  /** Overhead for AtomicInteger */
  public static final int ATOMIC_INTEGER;

  /** Overhead for AtomicBoolean */
  public static final int ATOMIC_BOOLEAN;

  /** Overhead for CopyOnWriteArraySet */
  public static final int COPYONWRITE_ARRAYSET;

  /** Overhead for CopyOnWriteArrayList */
  public static final int COPYONWRITE_ARRAYLIST;

  /** Overhead for timerange */
  public static final int TIMERANGE;

  /** Overhead for TimeRangeTracker */
  public static final int TIMERANGE_TRACKER;

  /** Overhead for KeyValueSkipListSet */
  public static final int KEYVALUE_SKIPLIST_SET;

  /* Are we running on jdk7? */
  private static final boolean JDK7;
  static {
    final String version = System.getProperty("java.version");
    // Verify String looks like this: 1.6.0_29
    if (!version.matches("\\d\\.\\d\\..*")) {
      throw new RuntimeException("Unexpected version format: " + version);
    }
    // Convert char to int
    int major = (int)(version.charAt(0) - '0');
    int minor = (int)(version.charAt(2) - '0');
    JDK7 = major == 1 && minor == 7;
  }

  /**
   * Method for reading the arc settings and setting overheads according
   * to 32-bit or 64-bit architecture.
   */
  static {
    //Default value is set to 8, covering the case when arcModel is unknown
    if (is32BitJVM()) {
      REFERENCE = 4;
    } else {
      REFERENCE = 8;
    }

    OBJECT = 2 * REFERENCE;

    ARRAY = align(3 * REFERENCE);

    ARRAYLIST = align(OBJECT + align(REFERENCE) + align(ARRAY) +
        (2 * Bytes.SIZEOF_INT));

    //noinspection PointlessArithmeticExpression
    BYTE_BUFFER = align(OBJECT + align(REFERENCE) + align(ARRAY) +
        (5 * Bytes.SIZEOF_INT) +
        (3 * Bytes.SIZEOF_BOOLEAN) + Bytes.SIZEOF_LONG);

    SHORT = align(OBJECT + Bytes.SIZEOF_SHORT);

    INTEGER = align(OBJECT + Bytes.SIZEOF_INT);

    LONG = align(OBJECT + Bytes.SIZEOF_LONG);

    FLOAT = align(OBJECT + Bytes.SIZEOF_FLOAT);

    DOUBLE = align(OBJECT + Bytes.SIZEOF_DOUBLE);

    MAP_ENTRY = align(OBJECT + 5 * REFERENCE + Bytes.SIZEOF_BOOLEAN);

    TREEMAP = align(OBJECT + (2 * Bytes.SIZEOF_INT) + align(7 * REFERENCE));

    // STRING is different size in jdk6 and jdk7. Just use what we estimate as size rather than
    // have a conditional on whether jdk7.
    STRING = (int) estimateBase(String.class, false);

    // CONCURRENT_HASHMAP is different size in jdk6 and jdk7; it looks like its different between
    // 23.6-b03 and 23.0-b21. Just use what we estimate as size rather than have a conditional on
    // whether jdk7.
    CONCURRENT_HASHMAP = (int) estimateBase(ConcurrentHashMap.class, false);

    CONCURRENT_HASHMAP_ENTRY = align(REFERENCE + OBJECT + (3 * REFERENCE) +
        (2 * Bytes.SIZEOF_INT));

    CONCURRENT_HASHMAP_SEGMENT = align(REFERENCE + OBJECT +
        (3 * Bytes.SIZEOF_INT) + Bytes.SIZEOF_FLOAT + ARRAY);

    // The size changes from jdk7 to jdk8, estimate the size rather than use a conditional
    CONCURRENT_SKIPLISTMAP = (int) estimateBase(ConcurrentSkipListMap.class, false);

    CONCURRENT_SKIPLISTMAP_ENTRY = align(
        align(OBJECT + (3 * REFERENCE)) + /* one node per entry */
        align((OBJECT + (3 * REFERENCE))/2)); /* one index per two entries */

    REENTRANT_LOCK = align(OBJECT + (3 * REFERENCE));

    ATOMIC_LONG = align(OBJECT + Bytes.SIZEOF_LONG);

    ATOMIC_INTEGER = align(OBJECT + Bytes.SIZEOF_INT);

    ATOMIC_BOOLEAN = align(OBJECT + Bytes.SIZEOF_BOOLEAN);

    COPYONWRITE_ARRAYSET = align(OBJECT + REFERENCE);

    COPYONWRITE_ARRAYLIST = align(OBJECT + (2 * REFERENCE) + ARRAY);

    TIMERANGE = align(ClassSize.OBJECT + Bytes.SIZEOF_LONG * 2 + Bytes.SIZEOF_BOOLEAN);

    TIMERANGE_TRACKER = align(ClassSize.OBJECT + Bytes.SIZEOF_LONG * 2);

    KEYVALUE_SKIPLIST_SET = align(OBJECT + REFERENCE);
  }

  /**
   * The estimate of the size of a class instance depends on whether the JVM
   * uses 32 or 64 bit addresses, that is it depends on the size of an object
   * reference. It is a linear function of the size of a reference, e.g.
   * 24 + 5*r where r is the size of a reference (usually 4 or 8 bytes).
   *
   * This method returns the coefficients of the linear function, e.g. {24, 5}
   * in the above example.
   *
   * @param cl A class whose instance size is to be estimated
   * @param debug debug flag
   * @return an array of 3 integers. The first integer is the size of the
   * primitives, the second the number of arrays and the third the number of
   * references.
   */
  @SuppressWarnings("unchecked")
  private static int [] getSizeCoefficients(Class cl, boolean debug) {
    int primitives = 0;
    int arrays = 0;
    //The number of references that a new object takes
    int references = nrOfRefsPerObj;
    int index = 0;

    for ( ; null != cl; cl = cl.getSuperclass()) {
      Field[] field = cl.getDeclaredFields();
      if (null != field) {
        for (Field aField : field) {
          if (Modifier.isStatic(aField.getModifiers())) continue;
          Class fieldClass = aField.getType();
          if (fieldClass.isArray()) {
            arrays++;
            references++;
          } else if (!fieldClass.isPrimitive()) {
            references++;
          } else {// Is simple primitive
            String name = fieldClass.getName();

            if (name.equals("int") || name.equals("I"))
              primitives += Bytes.SIZEOF_INT;
            else if (name.equals("long") || name.equals("J"))
              primitives += Bytes.SIZEOF_LONG;
            else if (name.equals("boolean") || name.equals("Z"))
              primitives += Bytes.SIZEOF_BOOLEAN;
            else if (name.equals("short") || name.equals("S"))
              primitives += Bytes.SIZEOF_SHORT;
            else if (name.equals("byte") || name.equals("B"))
              primitives += Bytes.SIZEOF_BYTE;
            else if (name.equals("char") || name.equals("C"))
              primitives += Bytes.SIZEOF_CHAR;
            else if (name.equals("float") || name.equals("F"))
              primitives += Bytes.SIZEOF_FLOAT;
            else if (name.equals("double") || name.equals("D"))
              primitives += Bytes.SIZEOF_DOUBLE;
          }
          if (debug) {
            if (LOG.isDebugEnabled()) {
              LOG.debug("" + index + " " + aField.getName() + " " + aField.getType());
            }
          }
          index++;
        }
      }
    }
    return new int [] {primitives, arrays, references};
  }

  /**
   * Estimate the static space taken up by a class instance given the
   * coefficients returned by getSizeCoefficients.
   *
   * @param coeff the coefficients
   *
   * @param debug debug flag
   * @return the size estimate, in bytes
   */
  private static long estimateBaseFromCoefficients(int [] coeff, boolean debug) {
    long prealign_size = coeff[0] + align(coeff[1] * ARRAY) + coeff[2] * REFERENCE;

    // Round up to a multiple of 8
    long size = align(prealign_size);
    if(debug) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Primitives=" + coeff[0] + ", arrays=" + coeff[1] +
            ", references(includes " + nrOfRefsPerObj +
            " for object overhead)=" + coeff[2] + ", refSize " + REFERENCE +
            ", size=" + size + ", prealign_size=" + prealign_size);
      }
    }
    return size;
  }

  /**
   * Estimate the static space taken up by the fields of a class. This includes
   * the space taken up by by references (the pointer) but not by the referenced
   * object. So the estimated size of an array field does not depend on the size
   * of the array. Similarly the size of an object (reference) field does not
   * depend on the object.
   *
   * @param cl class
   * @param debug debug flag
   * @return the size estimate in bytes.
   */
  @SuppressWarnings("unchecked")
  public static long estimateBase(Class cl, boolean debug) {
    return estimateBaseFromCoefficients( getSizeCoefficients(cl, debug), debug);
  }

  /**
   * Aligns a number to 8.
   * @param num number to align to 8
   * @return smallest number >= input that is a multiple of 8
   */
  public static int align(int num) {
    return (int)(align((long)num));
  }

  /**
   * Aligns a number to 8.
   * @param num number to align to 8
   * @return smallest number >= input that is a multiple of 8
   */
  public static long align(long num) {
    //The 7 comes from that the alignSize is 8 which is the number of bytes
    //stored and sent together
    return  ((num + 7) >> 3) << 3;
  }

  /**
   * Determines if we are running in a 32-bit JVM. Some unit tests need to
   * know this too.
   */
  public static boolean is32BitJVM() {
    return System.getProperty("sun.arch.data.model").equals("32");
  }

}

