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

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;

import org.apache.geode.annotations.Immutable;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.internal.JvmSizeUtils;
import org.apache.geode.unsafe.internal.sun.misc.Unsafe;

/**
 * This class supports allocating and freeing large amounts of addressable memory (i.e. slabs). It
 * also supports using an "address" to operate on the memory. Note that this class's implementation
 * is currently a singleton so all the methods on it are static.
 */
public class AddressableMemoryManager {
  @Immutable
  private static final Unsafe unsafe;
  private static final int ARRAY_BYTE_BASE_OFFSET;
  private static final String reason;
  static {
    Unsafe tmp = null;
    String tmpReason = null;
    try {
      tmp = new Unsafe();
    } catch (RuntimeException ignore) {
      tmpReason = ignore.toString();
    } catch (Error ignore) {
      tmpReason = ignore.toString();
    }
    reason = tmpReason;
    unsafe = tmp;
    ARRAY_BYTE_BASE_OFFSET = unsafe != null ? unsafe.arrayBaseOffset(byte[].class) : 0;
  }

  public static long allocate(int size) {
    if (unsafe == null) {
      throw new OutOfMemoryError("Off-heap memory is not available because: " + reason);
    }
    try {
      return unsafe.allocateMemory(size);
    } catch (OutOfMemoryError err) {
      String msg = "Failed creating " + size + " bytes of off-heap memory during cache creation.";
      if (err.getMessage() != null && !err.getMessage().isEmpty()) {
        msg += " Cause: " + err.getMessage();
      }
      if (!JvmSizeUtils.is64Bit() && size >= (1024 * 1024 * 1024)) {
        msg +=
            " The JVM looks like a 32-bit one. For large amounts of off-heap memory a 64-bit JVM is needed.";
      }
      throw new OutOfMemoryError(msg);
    }
  }

  public static void free(long addr) {
    unsafe.freeMemory(addr);
  }

  public static Slab allocateSlab(int size) {
    return new SlabImpl(size);
  }

  public static byte readByte(long addr) {
    return unsafe.getByte(addr);
  }

  public static char readChar(long addr) {
    return unsafe.getChar(null, addr);
  }

  public static short readShort(long addr) {
    return unsafe.getShort(null, addr);
  }

  public static int readInt(long addr) {
    return unsafe.getInt(null, addr);
  }

  public static int readIntVolatile(long addr) {
    return unsafe.getIntVolatile(null, addr);
  }

  public static long readLong(long addr) {
    return unsafe.getLong(null, addr);
  }

  public static long readLongVolatile(long addr) {
    return unsafe.getLongVolatile(null, addr);
  }

  public static void writeByte(long addr, byte value) {
    unsafe.putByte(addr, value);
  }

  public static void writeInt(long addr, int value) {
    unsafe.putInt(null, addr, value);
  }

  public static void writeIntVolatile(long addr, int value) {
    unsafe.putIntVolatile(null, addr, value);
  }

  public static boolean writeIntVolatile(long addr, int expected, int value) {
    return unsafe.compareAndSwapInt(null, addr, expected, value);
  }

  public static void writeLong(long addr, long value) {
    unsafe.putLong(null, addr, value);
  }

  public static void writeLongVolatile(long addr, long value) {
    unsafe.putLongVolatile(null, addr, value);
  }

  public static boolean writeLongVolatile(long addr, long expected, long value) {
    return unsafe.compareAndSwapLong(null, addr, expected, value);
  }

  public static void readBytes(long addr, byte[] bytes, int bytesOffset, int size) {
    // Throwing an Error instead of using the "assert" keyword because passing < 0 to
    // copyMemory(...) can lead to a core dump with some JVMs and we don't want to
    // require the -ea JVM flag.
    if (size < 0) {
      throw new AssertionError("Size=" + size + ", but size must be >= 0");
    }

    assert bytesOffset >= 0 : "byteOffset=" + bytesOffset;
    assert bytesOffset + size <= bytes.length : "byteOffset=" + bytesOffset + ",size=" + size
        + ",bytes.length=" + bytes.length;

    if (size == 0) {
      return; // No point in wasting time copying 0 bytes
    }
    unsafe.copyMemory(null, addr, bytes, ARRAY_BYTE_BASE_OFFSET + bytesOffset, size);
  }

  public static void copyMemory(long srcAddr, long dstAddr, long size) {
    unsafe.copyMemory(srcAddr, dstAddr, size);
  }

  public static void writeBytes(long addr, byte[] bytes, int bytesOffset, int size) {
    // Throwing an Error instead of using the "assert" keyword because passing < 0 to
    // copyMemory(...) can lead to a core dump with some JVMs and we don't want to
    // require the -ea JVM flag.
    if (size < 0) {
      throw new AssertionError("Size=" + size + ", but size must be >= 0");
    }

    assert bytesOffset >= 0 : "byteOffset=" + bytesOffset;
    assert bytesOffset + size <= bytes.length : "byteOffset=" + bytesOffset + ",size=" + size
        + ",bytes.length=" + bytes.length;

    if (size == 0) {
      return; // No point in wasting time copying 0 bytes
    }
    unsafe.copyMemory(bytes, ARRAY_BYTE_BASE_OFFSET + bytesOffset, null, addr, size);
  }

  public static void fill(long addr, int size, byte fill) {
    unsafe.setMemory(addr, size, fill);
  }

  @SuppressWarnings("rawtypes")
  @MakeNotStatic
  private static volatile Class dbbClass = null;
  @SuppressWarnings("rawtypes")
  @MakeNotStatic
  private static volatile Constructor dbbCtor = null;
  @MakeNotStatic
  private static volatile boolean dbbCreateFailed = false;
  @MakeNotStatic
  private static volatile Method dbbAddressMethod = null;
  @MakeNotStatic
  private static volatile boolean dbbAddressFailed = false;

  /**
   * Returns the address of the Unsafe memory for the first byte of a direct ByteBuffer. If the
   * buffer is not direct or the address can not be obtained return 0.
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  public static long getDirectByteBufferAddress(ByteBuffer bb) {
    if (!bb.isDirect()) {
      return 0L;
    }
    if (dbbAddressFailed) {
      return 0L;
    }
    Method m = dbbAddressMethod;
    if (m == null) {
      Class c = dbbClass;
      if (c == null) {
        try {
          c = Class.forName("java.nio.DirectByteBuffer");
        } catch (ClassNotFoundException e) {
          // throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
          dbbCreateFailed = true;
          dbbAddressFailed = true;
          return 0L;
        }
        dbbClass = c;
      }
      try {
        m = c.getDeclaredMethod("address");
      } catch (NoSuchMethodException | SecurityException e) {
        // throw new IllegalStateException("Could not get method DirectByteBuffer.address()", e);
        dbbClass = null;
        dbbAddressFailed = true;
        return 0L;
      }
      m.setAccessible(true);
      dbbAddressMethod = m;
    }
    try {
      return (Long) m.invoke(bb);
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
      // throw new IllegalStateException("Could not create an invoke DirectByteBuffer.address()",
      // e);
      dbbClass = null;
      dbbAddressMethod = null;
      dbbAddressFailed = true;
      return 0L;
    }
  }

  /**
   * Create a direct byte buffer given its address and size. The returned ByteBuffer will be direct
   * and use the memory at the given address.
   *
   * @return the created direct byte buffer or null if it could not be created.
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  static ByteBuffer createDirectByteBuffer(long address, int size) {
    if (dbbCreateFailed) {
      return null;
    }
    Constructor ctor = dbbCtor;
    if (ctor == null) {
      Class c = dbbClass;
      if (c == null) {
        try {
          c = Class.forName("java.nio.DirectByteBuffer");
        } catch (ClassNotFoundException e) {
          // throw new IllegalStateException("Could not find java.nio.DirectByteBuffer", e);
          dbbCreateFailed = true;
          dbbAddressFailed = true;
          return null;
        }
        dbbClass = c;
      }
      try {
        ctor = c.getDeclaredConstructor(long.class, int.class);
      } catch (NoSuchMethodException | SecurityException e) {
        // throw new IllegalStateException("Could not get constructor DirectByteBuffer(long, int)",
        // e);
        dbbClass = null;
        dbbCreateFailed = true;
        return null;
      }
      ctor.setAccessible(true);
      dbbCtor = ctor;
    }
    try {
      return (ByteBuffer) ctor.newInstance(address, size);
    } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
        | InvocationTargetException e) {
      // throw new IllegalStateException("Could not create an instance using DirectByteBuffer(long,
      // int)", e);
      dbbClass = null;
      dbbCtor = null;
      dbbCreateFailed = true;
      return null;
    }
  }

}
