/* Copyright (C) 2014 The Android Open Source Project
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file implements interfaces from the file jvm.h. This implementation
 * is licensed under the same terms as the file jvm.h.  The
 * copyright and license information for the file jvm.h follows.
 *
 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * Services that OpenJDK expects the VM to provide.
 */

#include <assert.h>
#include <dlfcn.h>
#include <limits.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>

#include <android-base/logging.h>

#include "../../libcore/ojluni/src/main/native/jvm.h"  // TODO(narayan): fix it

#include "base/macros.h"
#include "base/fast_exit.h"
#include "common_throws.h"
#include "gc/heap.h"
#include "handle_scope-inl.h"
#include "jni/java_vm_ext.h"
#include "jni/jni_internal.h"
#include "mirror/class_loader.h"
#include "mirror/string-inl.h"
#include "monitor.h"
#include "native/scoped_fast_native_object_access-inl.h"
#include "nativehelper/scoped_local_ref.h"
#include "nativehelper/scoped_utf_chars.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
#include "thread_list.h"
#include "verify_object.h"

#undef LOG_TAG
#define LOG_TAG "artopenjdk"

/* posix open() with extensions; used by e.g. ZipFile */
JNIEXPORT jint JVM_Open(const char* fname, jint flags, jint mode) {
    /*
     * Some code seems to want the special return value JVM_EEXIST if the
     * file open fails due to O_EXCL.
     */
    // Don't use JVM_O_DELETE, it's problematic with FUSE, see b/28901232.
    if (flags & JVM_O_DELETE) {
        LOG(FATAL) << "JVM_O_DELETE option is not supported (while opening: '"
                   << fname << "')";
    }

    flags |= O_CLOEXEC;
    int fd = TEMP_FAILURE_RETRY(open(fname, flags & ~JVM_O_DELETE, mode));
    if (fd < 0) {
        int err = errno;
        if (err == EEXIST) {
            return JVM_EEXIST;
        } else {
            return -1;
        }
    }

    return fd;
}

/* posix close() */
JNIEXPORT jint JVM_Close(jint fd) {
    // don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR
    return close(fd);
}

/* posix read() */
JNIEXPORT jint JVM_Read(jint fd, char* buf, jint nbytes) {
    return TEMP_FAILURE_RETRY(read(fd, buf, nbytes));
}

/* posix write(); is used to write messages to stderr */
JNIEXPORT jint JVM_Write(jint fd, char* buf, jint nbytes) {
    return TEMP_FAILURE_RETRY(write(fd, buf, nbytes));
}

/* posix lseek() */
JNIEXPORT jlong JVM_Lseek(jint fd, jlong offset, jint whence) {
#if !defined(__APPLE__)
    // NOTE: Using TEMP_FAILURE_RETRY here is busted for LP32 on glibc - the return
    // value will be coerced into an int32_t.
    //
    // lseek64 isn't specified to return EINTR so it shouldn't be necessary
    // anyway.
    return lseek64(fd, offset, whence);
#else
    // NOTE: This code is compiled for Mac OS but isn't ever run on that
    // platform.
    return lseek(fd, offset, whence);
#endif
}

/*
 * "raw monitors" seem to be expected to behave like non-recursive pthread
 * mutexes.  They're used by ZipFile.
 */
JNIEXPORT void* JVM_RawMonitorCreate(void) {
    pthread_mutex_t* mutex =
        reinterpret_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
    CHECK(mutex != nullptr);
    CHECK_PTHREAD_CALL(pthread_mutex_init, (mutex, nullptr), "JVM_RawMonitorCreate");
    return mutex;
}

JNIEXPORT void JVM_RawMonitorDestroy(void* mon) {
    CHECK_PTHREAD_CALL(pthread_mutex_destroy,
                       (reinterpret_cast<pthread_mutex_t*>(mon)),
                       "JVM_RawMonitorDestroy");
    free(mon);
}

JNIEXPORT jint JVM_RawMonitorEnter(void* mon) {
    return pthread_mutex_lock(reinterpret_cast<pthread_mutex_t*>(mon));
}

JNIEXPORT void JVM_RawMonitorExit(void* mon) {
    CHECK_PTHREAD_CALL(pthread_mutex_unlock,
                       (reinterpret_cast<pthread_mutex_t*>(mon)),
                       "JVM_RawMonitorExit");
}

JNIEXPORT char* JVM_NativePath(char* path) {
    return path;
}

JNIEXPORT jint JVM_GetLastErrorString(char* buf, int len) {
#if defined(__GLIBC__) || defined(__BIONIC__)
  if (len == 0) {
    return 0;
  }

  const int err = errno;
  char* result = strerror_r(err, buf, len);
  if (result != buf) {
    strncpy(buf, result, len);
    buf[len - 1] = '\0';
  }

  return strlen(buf);
#else
  UNUSED(buf);
  UNUSED(len);
  return -1;
#endif
}

JNIEXPORT int jio_fprintf(FILE* fp, const char* fmt, ...) {
    va_list args;

    va_start(args, fmt);
    int len = jio_vfprintf(fp, fmt, args);
    va_end(args);

    return len;
}

JNIEXPORT int jio_vfprintf(FILE* fp, const char* fmt, va_list args) {
    assert(fp != nullptr);
    return vfprintf(fp, fmt, args);
}

/* posix fsync() */
JNIEXPORT jint JVM_Sync(jint fd) {
    return TEMP_FAILURE_RETRY(fsync(fd));
}

JNIEXPORT void* JVM_FindLibraryEntry(void* handle, const char* name) {
    return dlsym(handle, name);
}

JNIEXPORT jlong JVM_CurrentTimeMillis([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz) {
    struct timeval tv;
    gettimeofday(&tv, (struct timezone *) nullptr);
    jlong when = tv.tv_sec * 1000LL + tv.tv_usec / 1000;
    return when;
}

/**
 * See the spec of this function in jdk.internal.misc.VM.
 * @return -1 if the system time isn't within  +/- 2^32 seconds from offset_secs
 */
JNIEXPORT jlong JVM_GetNanoTimeAdjustment([[maybe_unused]] JNIEnv*,
                                          [[maybe_unused]] jclass,
                                          jlong offset_secs) {
    struct timeval tv;
    // Note that we don't want the elapsed time here, but the system clock.
    // gettimeofday() doesn't provide nanosecond-level precision.
    // clock_gettime(CLOCK_REALTIME, tp) may provide nanosecond-level precision.
    // If it does support higher precision, we should switch both
    // JVM_CurrentTimeMillis and JVM_GetNanoTimeAdjustment to use clock_gettime
    // instead of gettimeofday() because various callers assume that
    // System.currentTimeMillis() and VM.getNanoTimeAdjustment(offset) use the
    // same time source.
    gettimeofday(&tv, (struct timezone *) nullptr);
    jlong sec_diff = ((jlong) tv.tv_sec) - offset_secs;
    const jlong max_diff = ((jlong) 1) << 32;
    const jlong min_diff = -max_diff;
    if (sec_diff >= max_diff || sec_diff <= min_diff) {
        return -1;
    }
    jlong usec_diff = sec_diff * 1000000LL + tv.tv_usec;
    return usec_diff * 1000;
}

JNIEXPORT jint JVM_Socket(jint domain, jint type, jint protocol) {
    return TEMP_FAILURE_RETRY(socket(domain, type, protocol));
}

JNIEXPORT jint JVM_InitializeSocketLibrary() {
  return 0;
}

int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {
  if ((intptr_t)count <= 0) return -1;
  return vsnprintf(str, count, fmt, args);
}

int jio_snprintf(char *str, size_t count, const char *fmt, ...) {
  va_list args;
  int len;
  va_start(args, fmt);
  len = jio_vsnprintf(str, count, fmt, args);
  va_end(args);
  return len;
}

JNIEXPORT jint JVM_SetSockOpt(jint fd, int level, int optname,
    const char* optval, int optlen) {
  return TEMP_FAILURE_RETRY(setsockopt(fd, level, optname, optval, optlen));
}

JNIEXPORT jint JVM_SocketShutdown(jint fd, jint howto) {
  return TEMP_FAILURE_RETRY(shutdown(fd, howto));
}

JNIEXPORT jint JVM_GetSockOpt(jint fd, int level, int optname, char* optval,
  int* optlen) {
  socklen_t len = *optlen;
  int cc = TEMP_FAILURE_RETRY(getsockopt(fd, level, optname, optval, &len));
  *optlen = len;
  return cc;
}

JNIEXPORT jint JVM_GetSockName(jint fd, struct sockaddr* addr, int* addrlen) {
  socklen_t len = *addrlen;
  int cc = TEMP_FAILURE_RETRY(getsockname(fd, addr, &len));
  *addrlen = len;
  return cc;
}

JNIEXPORT jint JVM_SocketAvailable(jint fd, jint* result) {
  if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, result)) < 0) {
      return JNI_FALSE;
  }

  return JNI_TRUE;
}

JNIEXPORT jint JVM_Send(jint fd, char* buf, jint nBytes, jint flags) {
  return TEMP_FAILURE_RETRY(send(fd, buf, nBytes, flags));
}

JNIEXPORT jint JVM_SocketClose(jint fd) {
  // Don't want TEMP_FAILURE_RETRY here -- file is closed even if EINTR.
  return close(fd);
}

JNIEXPORT jint JVM_Listen(jint fd, jint count) {
  return TEMP_FAILURE_RETRY(listen(fd, count));
}

JNIEXPORT jint JVM_Connect(jint fd, struct sockaddr* addr, jint addrlen) {
  return TEMP_FAILURE_RETRY(connect(fd, addr, addrlen));
}

JNIEXPORT int JVM_GetHostName(char* name, int namelen) {
  return TEMP_FAILURE_RETRY(gethostname(name, namelen));
}

JNIEXPORT jstring JVM_InternString(JNIEnv* env, jstring jstr) {
  art::ScopedFastNativeObjectAccess soa(env);
  art::ObjPtr<art::mirror::String> s = soa.Decode<art::mirror::String>(jstr);
  return soa.AddLocalReference<jstring>(s->Intern());
}

JNIEXPORT jlong JVM_FreeMemory(void) {
  return art::Runtime::Current()->GetHeap()->GetFreeMemory();
}

JNIEXPORT jlong JVM_TotalMemory(void) {
  return art::Runtime::Current()->GetHeap()->GetTotalMemory();
}

JNIEXPORT jlong JVM_MaxMemory(void) {
  return art::Runtime::Current()->GetHeap()->GetMaxMemory();
}

JNIEXPORT void JVM_GC(void) {
  if (art::Runtime::Current()->IsExplicitGcDisabled()) {
      LOG(INFO) << "Explicit GC skipped.";
      return;
  }
  art::Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references */ false);
}

JNIEXPORT __attribute__((noreturn)) void JVM_Exit(jint status) {
  LOG(INFO) << "System.exit called, status: " << status;
  art::Runtime::Current()->CallExitHook(status);
  // Unsafe to call exit() while threads may still be running. They would race
  // with static destructors.
  art::FastExit(status);
}

JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env,
                                 jstring javaFilename,
                                 jobject javaLoader,
                                 jclass caller) {
  ScopedUtfChars filename(env, javaFilename);
  if (filename.c_str() == nullptr) {
    return nullptr;
  }

  std::string error_msg;
  {
    art::JavaVMExt* vm = art::Runtime::Current()->GetJavaVM();
    bool success = vm->LoadNativeLibrary(env,
                                         filename.c_str(),
                                         javaLoader,
                                         caller,
                                         &error_msg);
    if (success) {
      return nullptr;
    }
  }

  // Don't let a pending exception from JNI_OnLoad cause a CheckJNI issue with NewStringUTF.
  env->ExceptionClear();
  return env->NewStringUTF(error_msg.c_str());
}

JNIEXPORT void JVM_StartThread(JNIEnv* env, jobject jthread, jlong stack_size, jboolean daemon) {
  art::Thread::CreateNativeThread(env, jthread, stack_size, daemon == JNI_TRUE);
}

JNIEXPORT void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio) {
  art::ScopedObjectAccess soa(env);
  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
  art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
  if (thread != nullptr) {
    thread->SetNativePriority(prio);
  }
}

JNIEXPORT void JVM_Yield([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass threadClass) {
  sched_yield();
}

JNIEXPORT void JVM_Sleep(JNIEnv* env,
                         [[maybe_unused]] jclass threadClass,
                         jobject java_lock,
                         jlong millis) {
  art::ScopedFastNativeObjectAccess soa(env);
  art::ObjPtr<art::mirror::Object> lock = soa.Decode<art::mirror::Object>(java_lock);
  art::Monitor::Wait(
      art::Thread::Current(), lock.Ptr(), millis, 0, true, art::ThreadState::kSleeping);
}

JNIEXPORT jobject JVM_CurrentThread(JNIEnv* env, [[maybe_unused]] jclass unused) {
  art::ScopedFastNativeObjectAccess soa(env);
  return soa.AddLocalReference<jobject>(soa.Self()->GetPeer());
}

JNIEXPORT void JVM_Interrupt(JNIEnv* env, jobject jthread) {
  art::ScopedFastNativeObjectAccess soa(env);
  art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
  art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
  if (thread != nullptr) {
    thread->Interrupt(soa.Self());
  }
}

JNIEXPORT jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clearInterrupted) {
  if (clearInterrupted) {
    return static_cast<art::JNIEnvExt*>(env)->GetSelf()->Interrupted() ? JNI_TRUE : JNI_FALSE;
  } else {
    art::ScopedFastNativeObjectAccess soa(env);
    art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_);
    art::Thread* thread = art::Thread::FromManagedThread(soa, jthread);
    return (thread != nullptr) ? thread->IsInterrupted() : JNI_FALSE;
  }
}

JNIEXPORT jboolean JVM_HoldsLock(JNIEnv* env, [[maybe_unused]] jclass unused, jobject jobj) {
  art::ScopedObjectAccess soa(env);
  art::ObjPtr<art::mirror::Object> object = soa.Decode<art::mirror::Object>(jobj);
  if (object == nullptr) {
    art::ThrowNullPointerException("object == null");
    return JNI_FALSE;
  }
  return soa.Self()->HoldsLock(object);
}

JNIEXPORT __attribute__((noreturn)) void JVM_SetNativeThreadName(
    [[maybe_unused]] JNIEnv* env,
    [[maybe_unused]] jobject jthread,
    [[maybe_unused]] jstring java_name) {
  UNIMPLEMENTED(FATAL) << "JVM_SetNativeThreadName is not implemented";
  UNREACHABLE();
}

JNIEXPORT __attribute__((noreturn)) jint JVM_IHashCode([[maybe_unused]] JNIEnv* env,
                                                       [[maybe_unused]] jobject javaObject) {
  UNIMPLEMENTED(FATAL) << "JVM_IHashCode is not implemented";
  UNREACHABLE();
}

JNIEXPORT __attribute__((noreturn)) jlong JVM_NanoTime([[maybe_unused]] JNIEnv* env,
                                                       [[maybe_unused]] jclass unused) {
  UNIMPLEMENTED(FATAL) << "JVM_NanoTime is not implemented";
  UNREACHABLE();
}

JNIEXPORT __attribute__((noreturn)) void JVM_ArrayCopy(JNIEnv* /* env */, jclass /* unused */, jobject /* javaSrc */,
                             jint /* srcPos */, jobject /* javaDst */, jint /* dstPos */,
                             jint /* length */) {
  UNIMPLEMENTED(FATAL) << "JVM_ArrayCopy is not implemented";
  UNREACHABLE();
}

JNIEXPORT __attribute__((noreturn)) jint JVM_FindSignal([[maybe_unused]] const char* name) {
  LOG(FATAL) << "JVM_FindSignal is not implemented";
  UNREACHABLE();
}

JNIEXPORT __attribute__((noreturn)) void* JVM_RegisterSignal([[maybe_unused]] jint signum,
                                                             [[maybe_unused]] void* handler) {
  LOG(FATAL) << "JVM_RegisterSignal is not implemented";
  UNREACHABLE();
}

JNIEXPORT __attribute__((noreturn)) jboolean JVM_RaiseSignal([[maybe_unused]] jint signum) {
  LOG(FATAL) << "JVM_RaiseSignal is not implemented";
  UNREACHABLE();
}

JNIEXPORT __attribute__((noreturn))  void JVM_Halt(jint code) {
  _exit(code);
}

JNIEXPORT jboolean JVM_IsNaN(jdouble d) {
  return isnan(d);
}
