// 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 <IOKit/IOMessage.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.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>

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

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, nullptr);  // this resolve the relative path
  if (newpath == nullptr) {
    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, void *mibp, size_t *sizep) {
  return sysctlbyname(name_chars, mibp, sizep, nullptr, 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")'`
//
// This may return NULL if `os_log_create` is not supported on this version of
// macOS. Use `log_if_possible` to log when supported.
static os_log_t JniOSLog() {
  static dispatch_once_t once_token;
  static os_log_t log = nullptr;
  // On macOS < 10.12, os_log_create is not available. Since we target 10.10,
  // this will be weakly linked and can be checked for availability at run
  // time.
  if (&os_log_create != nullptr) {
    dispatch_once(&once_token, ^{
      log = os_log_create("build.bazel", "jni");
      CHECK(log);
    });
  }
  return log;
}

// The macOS implementation asserts that `msg` be a string literal (not just a
// const char*), so we cannot use a function.
#define log_if_possible(msg)   \
  do {                         \
    os_log_t log = JniOSLog(); \
    if (log != nullptr) {      \
      os_log_debug(log, msg);  \
    }                          \
  } while (0);

// Protects all of the g_sleep_state_* statics.
static std::mutex g_sleep_state_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");

    __unused IOReturn success = IOPMAssertionCreateWithName(
        kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, reasonForActivity,
        &g_sleep_state_assertion);
    assert(success == kIOReturnSuccess);
    log_if_possible("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);
    __unused IOReturn success = IOPMAssertionRelease(g_sleep_state_assertion);
    assert(success == kIOReturnSuccess);
    g_sleep_state_assertion = kIOPMNullAssertionID;
    log_if_possible("sleep assertion released");
  }
  return 0;
}

typedef struct {
  // Port used to relay sleep call back messages.
  io_connect_t connect_port;
} 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:
      log_if_possible("suspend anomaly due to kIOMessageSystemWillSleep");
      suspend_callback(SuspensionReasonSleep);
      // This needs to be acknowledged to allow sleep.
      IOAllowPowerChange(state->connect_port, (intptr_t)message_argument);
      break;

    case kIOMessageSystemHasPoweredOn:
      // Note that Macs have a "Dark Wake" mode (also known as PowerNap) which
      // can have the processors (and disk and network) turn on.
      // (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).
      // 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.
      log_if_possible("suspend anomaly due to kIOMessageSystemHasPoweredOn");
      suspend_callback(SuspensionReasonWake);
      break;

    case kIOMessageSystemWillPowerOn:
    case kIOMessageSystemWillNotSleep:
      // We don't handle will not sleep. This can only occur is somebody else
      // cancels the sleep, and will never occur AFTER a
      // kIOMessageSystemWillSleep.
      // We don't handle will power on, we only care when it HAS powered on.
    default:
      break;
  }
}

void portable_start_suspend_monitoring() {
  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.
    // `/usr/bin/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.
    // 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 != nullptr);
    dispatch_source_set_event_handler(signal_source, ^{
      log_if_possible("suspend anomaly due to SIGCONT");
      suspend_callback(SuspensionReasonSIGCONT);
    });
    dispatch_resume(signal_source);
    signal_source =
        dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTSTP, 0, queue);
    CHECK(signal_source != nullptr);
    dispatch_source_set_event_handler(signal_source, ^{
      log_if_possible("suspend anomaly due to SIGTSTP");
      suspend_callback(SuspensionReasonSIGTSTP);
    });
    dispatch_resume(signal_source);
    log_if_possible("suspend monitoring registered");
  });
}

static std::atomic_int pressure_warning_count{0};
static std::atomic_int pressure_critical_count{0};

static void RegisterMemoryPressureHandler() {
  // To test use:
  // /usr/bin/log stream -level debug --predicate '(subsystem == "build.bazel")'
  // sudo memory_pressure -S -l warn
  // sudo memory_pressure -S -l critical
  static dispatch_once_t once_token;
  dispatch_once(&once_token, ^{
    dispatch_source_t source = dispatch_source_create(
        DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0,
        DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL,
        JniDispatchQueue());
    CHECK(source != nullptr);
    dispatch_source_set_event_handler(source, ^{
      dispatch_source_memorypressure_flags_t pressureLevel =
          dispatch_source_get_data(source);
      if (pressureLevel == DISPATCH_MEMORYPRESSURE_WARN) {
        log_if_possible("memory pressure warning anomaly");
        ++pressure_warning_count;
      } else if (pressureLevel == DISPATCH_MEMORYPRESSURE_CRITICAL) {
        log_if_possible("memory pressure critical anomaly");
        ++pressure_critical_count;
      }
    });
    dispatch_resume(source);
    log_if_possible("memory pressure handler registered");
  });
}

int portable_memory_pressure_warning_count() {
  RegisterMemoryPressureHandler();
  return pressure_warning_count;
}

int portable_memory_pressure_critical_count() {
  RegisterMemoryPressureHandler();
  return pressure_critical_count;
}

}  // namespace blaze_jni
