/******************************************************************************
 *
 *  Copyright (C) 2015 Google, Inc.
 *
 *  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.
 *
 ******************************************************************************/

#define LOG_TAG "bt_osi_wakelock"

#include <errno.h>
#include <fcntl.h>
#include <hardware/bluetooth.h>
#include <inttypes.h>
#include <limits.h>
#include <pthread.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <mutex>
#include <string>

#include "base/logging.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "osi/include/metrics.h"
#include "osi/include/osi.h"
#include "osi/include/thread.h"
#include "osi/include/wakelock.h"

using system_bt_osi::BluetoothMetricsLogger;

static bt_os_callouts_t* wakelock_os_callouts = NULL;
static bool is_native = true;

static const clockid_t CLOCK_ID = CLOCK_BOOTTIME;
static const char* WAKE_LOCK_ID = "bluetooth_timer";
static const std::string DEFAULT_WAKE_LOCK_PATH = "/sys/power/wake_lock";
static const std::string DEFAULT_WAKE_UNLOCK_PATH = "/sys/power/wake_unlock";
static std::string wake_lock_path;
static std::string wake_unlock_path;
static ssize_t locked_id_len = -1;
static pthread_once_t initialized = PTHREAD_ONCE_INIT;
static int wake_lock_fd = INVALID_FD;
static int wake_unlock_fd = INVALID_FD;

// Wakelock statistics for the "bluetooth_timer"
typedef struct {
  bool is_acquired;
  size_t acquired_count;
  size_t released_count;
  size_t acquired_errors;
  size_t released_errors;
  period_ms_t min_acquired_interval_ms;
  period_ms_t max_acquired_interval_ms;
  period_ms_t last_acquired_interval_ms;
  period_ms_t total_acquired_interval_ms;
  period_ms_t last_acquired_timestamp_ms;
  period_ms_t last_released_timestamp_ms;
  period_ms_t last_reset_timestamp_ms;
  int last_acquired_error;
  int last_released_error;
} wakelock_stats_t;

static wakelock_stats_t wakelock_stats;

// This mutex ensures that the functions that update and dump the statistics
// are executed serially.
static std::mutex stats_mutex;

static bt_status_t wakelock_acquire_callout(void);
static bt_status_t wakelock_acquire_native(void);
static bt_status_t wakelock_release_callout(void);
static bt_status_t wakelock_release_native(void);
static void wakelock_initialize(void);
static void wakelock_initialize_native(void);
static void reset_wakelock_stats(void);
static void update_wakelock_acquired_stats(bt_status_t acquired_status);
static void update_wakelock_released_stats(bt_status_t released_status);

void wakelock_set_os_callouts(bt_os_callouts_t* callouts) {
  wakelock_os_callouts = callouts;
  is_native = (wakelock_os_callouts == NULL);
  LOG_INFO(LOG_TAG, "%s set to %s", __func__,
           (is_native) ? "native" : "non-native");
}

bool wakelock_acquire(void) {
  pthread_once(&initialized, wakelock_initialize);

  bt_status_t status = BT_STATUS_FAIL;

  if (is_native)
    status = wakelock_acquire_native();
  else
    status = wakelock_acquire_callout();

  update_wakelock_acquired_stats(status);

  if (status != BT_STATUS_SUCCESS)
    LOG_ERROR(LOG_TAG, "%s unable to acquire wake lock: %d", __func__, status);

  return (status == BT_STATUS_SUCCESS);
}

static bt_status_t wakelock_acquire_callout(void) {
  return static_cast<bt_status_t>(
      wakelock_os_callouts->acquire_wake_lock(WAKE_LOCK_ID));
}

static bt_status_t wakelock_acquire_native(void) {
  if (wake_lock_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s lock not acquired, invalid fd", __func__);
    return BT_STATUS_PARM_INVALID;
  }

  if (wake_unlock_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s not acquiring lock: can't release lock", __func__);
    return BT_STATUS_PARM_INVALID;
  }

  long lock_name_len = strlen(WAKE_LOCK_ID);
  locked_id_len = write(wake_lock_fd, WAKE_LOCK_ID, lock_name_len);
  if (locked_id_len == -1) {
    LOG_ERROR(LOG_TAG, "%s wake lock not acquired: %s", __func__,
              strerror(errno));
    return BT_STATUS_FAIL;
  } else if (locked_id_len < lock_name_len) {
    // TODO (jamuraa): this is weird. maybe we should release and retry.
    LOG_WARN(LOG_TAG, "%s wake lock truncated to %zd chars", __func__,
             locked_id_len);
  }
  return BT_STATUS_SUCCESS;
}

bool wakelock_release(void) {
  pthread_once(&initialized, wakelock_initialize);

  bt_status_t status = BT_STATUS_FAIL;

  if (is_native)
    status = wakelock_release_native();
  else
    status = wakelock_release_callout();

  update_wakelock_released_stats(status);

  return (status == BT_STATUS_SUCCESS);
}

static bt_status_t wakelock_release_callout(void) {
  return static_cast<bt_status_t>(
      wakelock_os_callouts->release_wake_lock(WAKE_LOCK_ID));
}

static bt_status_t wakelock_release_native(void) {
  if (wake_unlock_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s lock not released, invalid fd", __func__);
    return BT_STATUS_PARM_INVALID;
  }

  ssize_t wrote_name_len = write(wake_unlock_fd, WAKE_LOCK_ID, locked_id_len);
  if (wrote_name_len == -1) {
    LOG_ERROR(LOG_TAG, "%s can't release wake lock: %s", __func__,
              strerror(errno));
  } else if (wrote_name_len < locked_id_len) {
    LOG_ERROR(LOG_TAG, "%s lock release only wrote %zd, assuming released",
              __func__, wrote_name_len);
  }
  return BT_STATUS_SUCCESS;
}

static void wakelock_initialize(void) {
  reset_wakelock_stats();

  if (is_native) wakelock_initialize_native();
}

static void wakelock_initialize_native(void) {
  LOG_DEBUG(LOG_TAG, "%s opening wake locks", __func__);

  if (wake_lock_path.empty()) wake_lock_path = DEFAULT_WAKE_LOCK_PATH;

  wake_lock_fd = open(wake_lock_path.c_str(), O_RDWR | O_CLOEXEC);
  if (wake_lock_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s can't open wake lock %s: %s", __func__,
              wake_lock_path.c_str(), strerror(errno));
    CHECK(wake_lock_fd != INVALID_FD);
  }

  if (wake_unlock_path.empty()) wake_unlock_path = DEFAULT_WAKE_UNLOCK_PATH;

  wake_unlock_fd = open(wake_unlock_path.c_str(), O_RDWR | O_CLOEXEC);
  if (wake_unlock_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s can't open wake unlock %s: %s", __func__,
              wake_unlock_path.c_str(), strerror(errno));
    CHECK(wake_unlock_fd != INVALID_FD);
  }
}

void wakelock_cleanup(void) {
  wake_lock_path.clear();
  wake_unlock_path.clear();
  initialized = PTHREAD_ONCE_INIT;
}

void wakelock_set_paths(const char* lock_path, const char* unlock_path) {
  if (lock_path) wake_lock_path = lock_path;

  if (unlock_path) wake_unlock_path = unlock_path;
}

static period_ms_t now(void) {
  struct timespec ts;
  if (clock_gettime(CLOCK_ID, &ts) == -1) {
    LOG_ERROR(LOG_TAG, "%s unable to get current time: %s", __func__,
              strerror(errno));
    return 0;
  }

  return (ts.tv_sec * 1000LL) + (ts.tv_nsec / 1000000LL);
}

// Reset the Bluetooth wakelock statistics.
// This function is thread-safe.
static void reset_wakelock_stats(void) {
  std::lock_guard<std::mutex> lock(stats_mutex);

  wakelock_stats.is_acquired = false;
  wakelock_stats.acquired_count = 0;
  wakelock_stats.released_count = 0;
  wakelock_stats.acquired_errors = 0;
  wakelock_stats.released_errors = 0;
  wakelock_stats.min_acquired_interval_ms = 0;
  wakelock_stats.max_acquired_interval_ms = 0;
  wakelock_stats.last_acquired_interval_ms = 0;
  wakelock_stats.total_acquired_interval_ms = 0;
  wakelock_stats.last_acquired_timestamp_ms = 0;
  wakelock_stats.last_released_timestamp_ms = 0;
  wakelock_stats.last_reset_timestamp_ms = now();
}

//
// Update the Bluetooth acquire wakelock statistics.
//
// This function should be called every time when the wakelock is acquired.
// |acquired_status| is the status code that was return when the wakelock was
// acquired.
// This function is thread-safe.
//
static void update_wakelock_acquired_stats(bt_status_t acquired_status) {
  const period_ms_t now_ms = now();

  std::lock_guard<std::mutex> lock(stats_mutex);

  if (acquired_status != BT_STATUS_SUCCESS) {
    wakelock_stats.acquired_errors++;
    wakelock_stats.last_acquired_error = acquired_status;
  }

  if (wakelock_stats.is_acquired) {
    return;
  }

  wakelock_stats.is_acquired = true;
  wakelock_stats.acquired_count++;
  wakelock_stats.last_acquired_timestamp_ms = now_ms;

  BluetoothMetricsLogger::GetInstance()->LogWakeEvent(
      system_bt_osi::WAKE_EVENT_ACQUIRED, "", "", now_ms);
}

//
// Update the Bluetooth release wakelock statistics.
//
// This function should be called every time when the wakelock is released.
// |released_status| is the status code that was return when the wakelock was
// released.
// This function is thread-safe.
//
static void update_wakelock_released_stats(bt_status_t released_status) {
  const period_ms_t now_ms = now();

  std::lock_guard<std::mutex> lock(stats_mutex);

  if (released_status != BT_STATUS_SUCCESS) {
    wakelock_stats.released_errors++;
    wakelock_stats.last_released_error = released_status;
  }

  if (!wakelock_stats.is_acquired) {
    return;
  }

  wakelock_stats.is_acquired = false;
  wakelock_stats.released_count++;
  wakelock_stats.last_released_timestamp_ms = now_ms;

  // Compute the acquired interval and update the statistics
  period_ms_t delta_ms = now_ms - wakelock_stats.last_acquired_timestamp_ms;
  if (delta_ms < wakelock_stats.min_acquired_interval_ms ||
      wakelock_stats.released_count == 1) {
    wakelock_stats.min_acquired_interval_ms = delta_ms;
  }
  if (delta_ms > wakelock_stats.max_acquired_interval_ms) {
    wakelock_stats.max_acquired_interval_ms = delta_ms;
  }
  wakelock_stats.last_acquired_interval_ms = delta_ms;
  wakelock_stats.total_acquired_interval_ms += delta_ms;

  BluetoothMetricsLogger::GetInstance()->LogWakeEvent(
      system_bt_osi::WAKE_EVENT_RELEASED, "", "", now_ms);
}

void wakelock_debug_dump(int fd) {
  const period_ms_t now_ms = now();

  std::lock_guard<std::mutex> lock(stats_mutex);

  // Compute the last acquired interval if the wakelock is still acquired
  period_ms_t delta_ms = 0;
  period_ms_t last_interval = wakelock_stats.last_acquired_interval_ms;
  period_ms_t min_interval = wakelock_stats.min_acquired_interval_ms;
  period_ms_t max_interval = wakelock_stats.max_acquired_interval_ms;
  period_ms_t ave_interval = 0;

  if (wakelock_stats.is_acquired) {
    delta_ms = now_ms - wakelock_stats.last_acquired_timestamp_ms;
    if (delta_ms > max_interval) max_interval = delta_ms;
    if (delta_ms < min_interval) min_interval = delta_ms;
    last_interval = delta_ms;
  }
  period_ms_t total_interval =
      wakelock_stats.total_acquired_interval_ms + delta_ms;

  if (wakelock_stats.acquired_count > 0)
    ave_interval = total_interval / wakelock_stats.acquired_count;

  dprintf(fd, "\nBluetooth Wakelock Statistics:\n");
  dprintf(fd, "  Is acquired                    : %s\n",
          wakelock_stats.is_acquired ? "true" : "false");
  dprintf(fd, "  Acquired/released count        : %zu / %zu\n",
          wakelock_stats.acquired_count, wakelock_stats.released_count);
  dprintf(fd, "  Acquired/released error count  : %zu / %zu\n",
          wakelock_stats.acquired_errors, wakelock_stats.released_errors);
  dprintf(fd, "  Last acquire/release error code: %d / %d\n",
          wakelock_stats.last_acquired_error,
          wakelock_stats.last_released_error);
  dprintf(fd, "  Last acquired time (ms)        : %llu\n",
          (unsigned long long)last_interval);
  dprintf(fd, "  Acquired time min/max/avg (ms) : %llu / %llu / %llu\n",
          (unsigned long long)min_interval, (unsigned long long)max_interval,
          (unsigned long long)ave_interval);
  dprintf(fd, "  Total acquired time (ms)       : %llu\n",
          (unsigned long long)total_interval);
  dprintf(
      fd, "  Total run time (ms)            : %llu\n",
      (unsigned long long)(now_ms - wakelock_stats.last_reset_timestamp_ms));
}
