// Copyright 2014 The Bazel Authors. All rights reserved.
//
// 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.

#include <jni.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <string>

#include "src/main/native/unix_jni.h"

// Returns the field ID for FileDescriptor.fd.
static jfieldID GetFileDescriptorField(JNIEnv *env) {
  // See http://java.sun.com/docs/books/jni/html/fldmeth.html#26855
  static jclass fd_class = NULL;
  if (fd_class == NULL) { /* note: harmless race condition */
    jclass local = env->FindClass("java/io/FileDescriptor");
    CHECK(local != NULL);
    fd_class = static_cast<jclass>(env->NewGlobalRef(local));
  }
  static jfieldID fieldId = NULL;
  if (fieldId == NULL) { /* note: harmless race condition */
    fieldId = env->GetFieldID(fd_class, "fd", "I");
    CHECK(fieldId != NULL);
  }
  return fieldId;
}

// Returns the UNIX filedescriptor from a java.io.FileDescriptor instance.
static jint GetUnixFileDescriptor(JNIEnv *env, jobject fd_obj) {
  return env->GetIntField(fd_obj, GetFileDescriptorField(env));
}

// Sets the UNIX filedescriptor of a java.io.FileDescriptor instance.
static void SetUnixFileDescriptor(JNIEnv *env, jobject fd_obj, jint fd) {
  env->SetIntField(fd_obj, GetFileDescriptorField(env), fd);
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    socket
 * Signature: (Ljava/io/FileDescriptor;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_socket(JNIEnv *env,
                                               jclass clazz,
                                               jobject fd_sock) {
  int sock;
  if ((sock = ::socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
    ::PostException(env, errno, ::ErrorMessage(errno));
    return;
  }
  SetUnixFileDescriptor(env, fd_sock, sock);
}

// Initialize "addr" from "name_chars", reporting error and returning
// false on failure.
static bool InitializeSockaddr(JNIEnv *env,
                               struct sockaddr_un *addr,
                               const char* name_chars) {
  memset(addr, 0, sizeof *addr);
  addr->sun_family = AF_UNIX;
  // Note: UNIX_PATH_MAX is quite small!
  if (strlen(name_chars) >= sizeof(addr->sun_path)) {
    ::PostFileException(env, ENAMETOOLONG, name_chars);
    return false;
  }
  strcpy((char*) &addr->sun_path, name_chars);
  return true;
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    bind
 * Signature: (Ljava/io/FileDescriptor;Ljava/lang/String;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_bind(JNIEnv *env,
                                             jclass clazz,
                                             jobject fd_svr,
                                             jstring name) {
  int svr_sock = GetUnixFileDescriptor(env, fd_svr);
  const char* name_chars = env->GetStringUTFChars(name, NULL);
  struct sockaddr_un addr;
  if (InitializeSockaddr(env, &addr, name_chars) &&
      ::bind(svr_sock, (struct sockaddr *) &addr, sizeof addr) < 0) {
    ::PostException(env, errno, ::ErrorMessage(errno));
  }
  env->ReleaseStringUTFChars(name, name_chars);
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    listen
 * Signature: (Ljava/io/FileDescriptor;I)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_listen(JNIEnv *env,
                                               jclass clazz,
                                               jobject fd_svr,
                                               jint backlog) {
  int svr_sock = GetUnixFileDescriptor(env, fd_svr);
  if (::listen(svr_sock, backlog) < 0) {
    ::PostException(env, errno, ::ErrorMessage(errno));
  }
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    select
 * Signature: (L[java/io/FileDescriptor;[java/io/FileDescriptor;[java/io/FileDescriptor;J)Ljava/io/FileDescriptor
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_poll(JNIEnv *env,
                                               jclass clazz,
                                               jobject rfds_svr,
                                               jlong timeoutMillis) {
  // TODO(bazel-team): Handle Unix signals, namely SIGTERM.

  // Copy Java FD into pollfd
  pollfd pollfd;
  pollfd.fd = GetUnixFileDescriptor(env, rfds_svr);
  pollfd.events = POLLIN;
  pollfd.revents = 0;

  int count = poll(&pollfd, 1, timeoutMillis);
  if (count == 0) {
    // throws a timeout exception.
    ::PostException(env, ETIMEDOUT, ::ErrorMessage(ETIMEDOUT));
  } else if (count < 0) {
    ::PostException(env, errno, ::ErrorMessage(errno));
  }
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    accept
 * Signature: (Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_accept(JNIEnv *env,
                                               jclass clazz,
                                               jobject fd_svr,
                                               jobject fd_cli) {
  int svr_sock = GetUnixFileDescriptor(env, fd_svr);
  int cli_sock;
  if ((cli_sock = ::accept(svr_sock, NULL, NULL)) < 0) {
    ::PostException(env, errno, ::ErrorMessage(errno));
    return;
  }
  SetUnixFileDescriptor(env, fd_cli, cli_sock);
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    close
 * Signature: (Ljava/io/FileDescriptor;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_close(JNIEnv *env,
                                              jclass clazz,
                                              jobject fd_svr) {
  int svr_sock = GetUnixFileDescriptor(env, fd_svr);
  if (::close(svr_sock) < 0) {
    ::PostException(env, errno, ::ErrorMessage(errno));
  }
  SetUnixFileDescriptor(env, fd_svr, -1);
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    connect
 * Signature: (Ljava/io/FileDescriptor;Ljava/lang/String;)V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_connect(JNIEnv *env,
                                                jclass clazz,
                                                jobject fd_cli,
                                                jstring name) {
  const char* name_chars = env->GetStringUTFChars(name, NULL);
  jint cli_sock = GetUnixFileDescriptor(env, fd_cli);
  if (cli_sock == -1) {
    ::PostFileException(env, ENOTSOCK, name_chars);
  } else {
    struct sockaddr_un addr;
    if (InitializeSockaddr(env, &addr, name_chars)) {
      if (::connect(cli_sock, (struct sockaddr *) &addr, sizeof addr) < 0) {
        ::PostException(env, errno, ::ErrorMessage(errno));
      }
    }
  }
  env->ReleaseStringUTFChars(name, name_chars);
}

/*
 * Class:     com.google.devtools.build.lib.unix.LocalSocket
 * Method:    shutdown()
 * Signature: (Ljava/io/FileDescriptor;I)V
 * Parameters: code: 0 to shutdown input and 1 to shutdown output.
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocket_shutdown(JNIEnv *env,
                                                 jclass clazz,
                                                 jobject fd,
                                                 jint code) {
  int action;
  if (code == 0) {
    action = SHUT_RD;
  } else {
    CHECK(code == 1);
    action = SHUT_WR;
  }

  int sock = GetUnixFileDescriptor(env, fd);
  if (shutdown(sock, action) < 0) {
    ::PostException(env, errno, ::ErrorMessage(errno));
  }
}

// TODO(bazel-team): These methods were removed in JDK8, so they
// can be removed when we are no longer using JDK7.  See note in
// LocalSocketImpl.
static jmethodID increment_use_count_;
static jmethodID decrement_use_count_;

// >=JDK8
static jmethodID fd_attach_;
static jmethodID fd_close_all_;

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocketImpl_init(JNIEnv *env, jclass ignored) {
  jclass cls = env->FindClass("java/io/FileDescriptor");
  if (cls == NULL) {
    cls = env->FindClass("java/lang/NoClassDefFoundError");
    env->ThrowNew(cls, "FileDescriptor class not found");
    return;
  }

  // JDK7
  increment_use_count_ =
      env->GetMethodID(cls, "incrementAndGetUseCount", "()I");
  if (increment_use_count_ != NULL) {
    decrement_use_count_ =
        env->GetMethodID(cls, "decrementAndGetUseCount", "()I");
  } else {
    // JDK8
    env->ExceptionClear();  // The pending exception from increment_use_count_

    fd_attach_ = env->GetMethodID(cls, "attach", "(Ljava/io/Closeable;)V");
    fd_close_all_ = env->GetMethodID(cls, "closeAll", "(Ljava/io/Closeable;)V");

    if (fd_attach_ == NULL || fd_close_all_ == NULL) {
      cls = env->FindClass("java/lang/NoSuchMethodError");
      env->ThrowNew(cls, "FileDescriptor methods not found");
      return;
    }
  }
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocketImpl_ref(JNIEnv *env, jclass clazz,
                                                jobject fd, jobject closer) {
  if (increment_use_count_ != NULL) {
    env->CallIntMethod(fd, increment_use_count_);
  }

  if (fd_attach_ != NULL) {
    env->CallVoidMethod(fd, fd_attach_, closer);
  }
}

extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocketImpl_unref(JNIEnv *env, jclass clazz,
                                                  jobject fd) {
  if (decrement_use_count_ != NULL) {
    env->CallIntMethod(fd, decrement_use_count_);
    return true;
  }
  return false;
}

extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_unix_LocalSocketImpl_close0(JNIEnv *env, jclass clazz,
                                                   jobject fd,
                                                   jobject closeable) {
  if (fd_close_all_ != NULL) {
    env->CallVoidMethod(fd, fd_close_all_, closeable);
    return true;
  }
  // This will happen if fd_close_all_ is NULL, which means we are running in
  // <=JDK7, which means that the caller needs to invoke close() explicitly.
  return false;
}
