// 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 "src/main/native/unix_jni.h"

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <IOKit/IOMessage.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <os/log.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/syslimits.h>
#include <sys/types.h>
#include <sys/xattr.h>

#include <atomic>
// Linting disabled for this line because for google code we could use
// absl::Mutex but we cannot yet because Bazel doesn't depend on absl.
#include <mutex>  // NOLINT
#include <string>

namespace blaze_jni {

const int PATH_MAX2 = PATH_MAX * 2;

using std::string;

// See unix_jni.h.
string ErrorMessage(int error_number) {
  char buf[1024] = "";
  if (strerror_r(error_number, buf, sizeof buf) < 0) {
    snprintf(buf, sizeof buf, "strerror_r(%d): errno %d", error_number, errno);
  }

  return string(buf);
}


int portable_fstatat(
    int dirfd, char *name, portable_stat_struct *statbuf, int flags) {
  char dirPath[PATH_MAX2];  // Have enough room for relative path

  // No fstatat under darwin, simulate it
  if (flags != 0) {
    // We don't support any flags
    errno = ENOSYS;
    return -1;
  }
  if (strlen(name) == 0 || name[0] == '/') {
    // Absolute path, simply stat
    return portable_stat(name, statbuf);
  }
  // Relative path, construct an absolute path
  if (fcntl(dirfd, F_GETPATH, dirPath) == -1) {
    return -1;
  }
  int l = strlen(dirPath);
  if (dirPath[l-1] != '/') {
    // dirPath is twice the PATH_MAX size, we always have room for the extra /
    dirPath[l] = '/';
    dirPath[l+1] = 0;
    l++;
  }
  strncat(dirPath, name, PATH_MAX2-l-1);
  char *newpath = realpath(dirPath, NULL);  // this resolve the relative path
  if (newpath == NULL) {
    return -1;
  }
  int r = portable_stat(newpath, statbuf);
  free(newpath);
  return r;
}

int StatSeconds(const portable_stat_struct &statbuf, StatTimes t) {
  switch (t) {
    case STAT_ATIME:
      return statbuf.st_atime;
    case STAT_CTIME:
      return statbuf.st_ctime;
    case STAT_MTIME:
      return statbuf.st_mtime;
    default:
      CHECK(false);
  }
}

int StatNanoSeconds(const portable_stat_struct &statbuf, StatTimes t) {
  switch (t) {
    case STAT_ATIME:
      return statbuf.st_atimespec.tv_nsec;
    case STAT_CTIME:
      return statbuf.st_ctimespec.tv_nsec;
    case STAT_MTIME:
      return statbuf.st_mtimespec.tv_nsec;
    default:
      CHECK(false);
  }
}

ssize_t portable_getxattr(const char *path, const char *name, void *value,
                          size_t size, bool *attr_not_found) {
  ssize_t result = getxattr(path, name, value, size, 0, 0);
  *attr_not_found = (errno == ENOATTR);
  return result;
}

ssize_t portable_lgetxattr(const char *path, const char *name, void *value,
                           size_t size, bool *attr_not_found) {
  ssize_t result = getxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
  *attr_not_found = (errno == ENOATTR);
  return result;
}

int portable_sysctlbyname(const char *name_chars, long *mibp, size_t *sizep) {
  return sysctlbyname(name_chars, mibp, sizep, NULL, 0);
}

// Queue used for all of our anomaly tracking.
static dispatch_queue_t JniDispatchQueue() {
  static dispatch_once_t once_token;
  static dispatch_queue_t queue;
  dispatch_once(&once_token, ^{
    queue = dispatch_queue_create("build.bazel.jni", DISPATCH_QUEUE_SERIAL);
    CHECK(queue);
  });
  return queue;
}

// Log used for all of our anomaly logging.
// Logging can be traced using:
// `log stream -level debug --predicate '(subsystem == "build.bazel")'`
static os_log_t JniOSLog() {
  static dispatch_once_t once_token;
  static os_log_t log;
  dispatch_once(&once_token, ^{
    log = os_log_create("build.bazel", "jni");
    CHECK(log);
  });
  return log;
}

// Protects all of the g_sleep_state_* statics.
// value is "leaked" intentionally because std::mutex is not trivially
// destructible at this time, g_sleep_state_mutex is a singleton, and
// leaking it has no consequences.
static std::mutex *g_sleep_state_mutex = new std::mutex;

// Keep track of our pushes and pops of sleep state.
static int g_sleep_state_stack = 0;

// Our assertion for disabling sleep.
static IOPMAssertionID g_sleep_state_assertion = kIOPMNullAssertionID;

int portable_push_disable_sleep() {
  std::lock_guard<std::mutex> lock(*g_sleep_state_mutex);
  assert(g_sleep_state_stack >= 0);
  if (g_sleep_state_stack == 0) {
    assert(g_sleep_state_assertion == kIOPMNullAssertionID);
    CFStringRef reasonForActivity = CFSTR("build.bazel");

    IOReturn success = IOPMAssertionCreateWithName(
        kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, reasonForActivity,
        &g_sleep_state_assertion);
    assert(success == kIOReturnSuccess);
    os_log_debug(JniOSLog(), "sleep assertion created");
  }
  g_sleep_state_stack += 1;
  return 0;
}

int portable_pop_disable_sleep() {
  std::lock_guard<std::mutex> lock(*g_sleep_state_mutex);
  assert(g_sleep_state_stack > 0);
  g_sleep_state_stack -= 1;
  if (g_sleep_state_stack == 0) {
    assert(g_sleep_state_assertion != kIOPMNullAssertionID);
    IOReturn success = IOPMAssertionRelease(g_sleep_state_assertion);
    assert(success == kIOReturnSuccess);
    g_sleep_state_assertion = kIOPMNullAssertionID;
    os_log_debug(JniOSLog(), "sleep assertion released");
  }
  return 0;
}

typedef struct {
  // Port used to relay sleep call back messages.
  io_connect_t connect_port;

  // Count of suspensions. Atomic because it can be read from any java thread
  // and is written to from a dispatch_queue thread.
  std::atomic_int suspend_count;
} SuspendState;

static void SleepCallBack(void *refcon, io_service_t service,
                          natural_t message_type, void *message_argument) {
  SuspendState *state = (SuspendState *)refcon;
  switch (message_type) {
    case kIOMessageCanSystemSleep:
      // This needs to be handled to allow sleep.
      IOAllowPowerChange(state->connect_port, (intptr_t)message_argument);
      break;

    case kIOMessageSystemWillSleep:
      os_log_debug(JniOSLog(),
                   "suspend anomaly due to kIOMessageSystemWillSleep");
      ++state->suspend_count;
      // This needs to be acknowledged to allow sleep.
      IOAllowPowerChange(state->connect_port, (intptr_t)message_argument);
      break;

    case kIOMessageSystemWillNotSleep:
      os_log_debug(
          JniOSLog(),
          "suspend anomaly cancelled due to kIOMessageSystemWillNotSleep");
      --state->suspend_count;
      break;

    case kIOMessageSystemWillPowerOn:
    case kIOMessageSystemHasPoweredOn:
      // We increment g_suspend_count when we are alerted to the sleep as
      // opposed to when we wake up, because Macs have a "Dark Wake" mode (also
      // known as PowerNap) which is when the processors (and disk and network)
      // turn on for brief periods of time
      // (https://support.apple.com/en-us/HT204032). Dark Wake does NOT trigger
      // PowerOn messages through our sleep callbacks, but can allow
      // builds to proceed for a considerable amount of time (for example if
      // Time Machine is performing a back up).
      // There is currently a race condition where a build may finish
      // between the time we receive the kIOMessageSystemWillSleep and the
      // machine actually goes to sleep (roughly 20 seconds in my experiments)
      // or between the time we receive the kIOMessageSystemWillSleep and
      // kIOMessageSystemWillNotSleep. This will result in us reporting that the
      // build was suspended when it wasn't. I haven't come up with an smart way
      // of avoiding this issue, but I don't think we really care. Over
      // reporting "suspensions" is better than under reporting them.
    default:
      break;
  }
}

int portable_suspend_count() {
  static dispatch_once_t once_token;
  static SuspendState suspend_state;
  dispatch_once(&once_token, ^{
    dispatch_queue_t queue = JniDispatchQueue();
    IONotificationPortRef notifyPortRef;
    io_object_t notifierObject;

    // Register to receive system sleep notifications.
    // Testing needs to be done manually. Use the logging to verify
    // that sleeps are being caught here.
    // `log stream -level debug --predicate '(subsystem == "build.bazel")'`
    suspend_state.connect_port = IORegisterForSystemPower(
        &suspend_state, &notifyPortRef, SleepCallBack, &notifierObject);
    CHECK(suspend_state.connect_port != MACH_PORT_NULL);
    IONotificationPortSetDispatchQueue(notifyPortRef, queue);

    // Register to deal with SIGCONT.
    // We register for SIGCONT because we can't catch SIGSTOP and we can't
    // distinguish a SIGCONT after a SIGSTOP from a SIGCONT after SIGTSTP.
    // We do have the potential of "over counting" suspensions if you send
    // multiple SIGCONTs to a process without a previous SIGSTOP/SIGTSTP,
    // but there is no reason to send a SIGCONT without a SIGSTOP/SIGTSTP, and
    // having this functionality gives us some ability to unit test suspension
    // counts.
    sig_t signal_val = signal(SIGCONT, SIG_IGN);
    CHECK(signal_val != SIG_ERR);
    dispatch_source_t signal_source =
        dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGCONT, 0, queue);
    CHECK(signal_source != NULL);
    dispatch_source_set_event_handler(signal_source, ^{
      os_log_debug(JniOSLog(), "suspend anomaly due to SIGCONT");
      ++suspend_state.suspend_count;
    });
    dispatch_resume(signal_source);
  });
  return suspend_state.suspend_count;
}

int portable_memory_pressure_warning_count() {
  // To test use:
  // log stream -level debug --predicate '(subsystem == "build.bazel")'
  // sudo memory_pressure -S -l warn
  static dispatch_once_t once_token;
  static std::atomic_int warning_count;
  dispatch_once(&once_token, ^{
    dispatch_source_t source = dispatch_source_create(
        DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_WARN,
        JniDispatchQueue());
    CHECK(source != NULL);
    dispatch_source_set_event_handler(source, ^{
      dispatch_source_memorypressure_flags_t pressureLevel =
          dispatch_source_get_data(source);
      if (pressureLevel == DISPATCH_MEMORYPRESSURE_WARN) {
        os_log_debug(JniOSLog(), "memory pressure warning anomaly");
        ++warning_count;
      }
    });
    dispatch_resume(source);
  });
  return warning_count;
}

int portable_memory_pressure_critical_count() {
  // To test use:
  // log stream -level debug --predicate '(subsystem == "build.bazel")'
  // sudo memory_pressure -S -l critical
  static dispatch_once_t once_token;
  static std::atomic_int critical_count;
  dispatch_once(&once_token, ^{
    dispatch_source_t source = dispatch_source_create(
        DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0,
        DISPATCH_MEMORYPRESSURE_CRITICAL, JniDispatchQueue());
    CHECK(source != NULL);
    dispatch_source_set_event_handler(source, ^{
      dispatch_source_memorypressure_flags_t pressureLevel =
          dispatch_source_get_data(source);
      if (pressureLevel == DISPATCH_MEMORYPRESSURE_CRITICAL) {
        os_log_debug(JniOSLog(), "memory pressure critical anomaly");
        ++critical_count;
      }
    });
    dispatch_resume(source);
  });
  return critical_count;
}

}  // namespace blaze_jni
