//
//  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.
//
#include "core_stack.h"

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <condition_variable>
#include <mutex>
#include <string>

#include <hardware/bluetooth.h>
#include <hardware/hardware.h>

// TODO(armansito): Remove this line and use base/logging.h instead.
#define LOG_TAG "bluetooth_daemon"

#include "logging_helpers.h"

extern "C" {
#include "btcore/include/hal_util.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
}  // extern "C"

namespace {

std::mutex mutex;
std::condition_variable synchronize;
bool instantiated = false;

void AdapterStateChangedCallback(bt_state_t state) {
  LOG_INFO(LOG_TAG, "Bluetooth state:%s", BtStateText(state));
  std::lock_guard<std::mutex> lock(mutex);
  synchronize.notify_one();
}

void CallbackThreadCallback(bt_cb_thread_evt evt) {
  LOG_INFO(LOG_TAG, "%s: %s", __func__, BtEventText(evt));
}

// TODO(icoolidge): Audit how these os callouts should be
// implemented (or nulled) for systems w/out wakelocks.
bool SetWakeAlarmCallback(uint64_t delay_millis,
                          UNUSED_ATTR bool should_wake,
                          alarm_cb cb,
                          void *data) {
  static timer_t timer;
  static bool timer_created;

  if (!timer_created) {
    struct sigevent sigevent;
    memset(&sigevent, 0, sizeof(sigevent));
    sigevent.sigev_notify = SIGEV_THREAD;
    sigevent.sigev_notify_function = (void (*)(union sigval))cb;
    sigevent.sigev_value.sival_ptr = data;
    timer_create(CLOCK_MONOTONIC, &sigevent, &timer);
    timer_created = true;
  }

  struct itimerspec new_value;
  new_value.it_value.tv_sec = delay_millis / 1000;
  new_value.it_value.tv_nsec = (delay_millis % 1000) * 1000 * 1000;
  new_value.it_interval.tv_sec = 0;
  new_value.it_interval.tv_nsec = 0;
  timer_settime(timer, 0, &new_value, nullptr);

  return true;
}

// Dummy implementation due to no wakelocks.
int AcquireWakeLock(UNUSED_ATTR const char *lock_name) {
  return BT_STATUS_SUCCESS;
}

// Dummy implementation due to no wakelocks.
int ReleaseWakeLock(UNUSED_ATTR const char *lock_name) {
  return BT_STATUS_SUCCESS;
}

void GenericDevicePropertiesCallback(bt_status_t status,
                                     bt_bdaddr_t *remote_address,
                                     int num_properties,
                                     bt_property_t *properties) {
  if (status != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: %s", __func__, BtStatusText(status));
    return;
  }

  if (!remote_address) {
    LOG_INFO(LOG_TAG, "%s", "Local adapter properties:");
  }

  for (int i = 0; i < num_properties; ++i) {
    bt_property_t *prop = &properties[i];
    switch (prop->type) {
      case BT_PROPERTY_BDADDR: {
        std::string text =
            BtAddrString(reinterpret_cast<bt_bdaddr_t *>(prop->val));
        LOG_INFO(LOG_TAG, "%s: %s", BtPropertyText(prop->type), text.c_str());
        break;
      }
      case BT_PROPERTY_ADAPTER_SCAN_MODE: {
        bt_scan_mode_t *mode = reinterpret_cast<bt_scan_mode_t *>(prop->val);
        LOG_INFO(LOG_TAG, "%s: %s", BtPropertyText(prop->type), BtScanModeText(*mode));
        std::lock_guard<std::mutex> lock(mutex);
        synchronize.notify_one();
        break;
      }
      case BT_PROPERTY_BDNAME: {
        bt_bdname_t *name = reinterpret_cast<bt_bdname_t *>(prop->val);
        LOG_INFO(LOG_TAG, "%s: %s", BtPropertyText(prop->type),
                 reinterpret_cast<char *>(name->name));
        std::lock_guard<std::mutex> lock(mutex);
        synchronize.notify_one();
        break;
      }
      default:
        LOG_INFO(LOG_TAG, "%s: %s", __func__, BtPropertyText(prop->type));
        break;
    }
  }
}

void AclStateChangedCallback(bt_status_t status, bt_bdaddr_t *remote_bd_addr,
                             bt_acl_state_t state) {
  if (status != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: %s", __func__, BtStatusText(status));
    return;
  }

  std::string text = BtAddrString(remote_bd_addr);
  LOG_INFO(LOG_TAG, "%s: %s: %s", __func__, text.c_str(), BtAclText(state));
}

void LocalAdapterPropertiesCallback(bt_status_t status, int num_properties,
                                    bt_property_t *properties) {
  GenericDevicePropertiesCallback(status, nullptr, num_properties, properties);
}

bt_callbacks_t bt_callbacks = {
  sizeof(bt_callbacks_t),
  AdapterStateChangedCallback,
  LocalAdapterPropertiesCallback,
  GenericDevicePropertiesCallback,
  nullptr, /* device_found_cb */
  nullptr, /* discovery_state_changed_cb */
  nullptr, /* pin_request_cb  */
  nullptr, /* ssp_request_cb  */
  nullptr, /* bond_state_changed_cb */
  AclStateChangedCallback,
  CallbackThreadCallback,
  nullptr, /* dut_mode_recv_cb */
  nullptr, /* le_test_mode_cb */
  nullptr  /* energy_info_cb */
};

bt_os_callouts_t callouts = {
  sizeof(bt_os_callouts_t),
  SetWakeAlarmCallback,
  AcquireWakeLock,
  ReleaseWakeLock
};

}  // namespace

namespace bluetooth {

// The real CoreStack implementation to be used in production code.
class CoreStackImpl : public CoreStack {
 public:
  CoreStackImpl();
  ~CoreStackImpl() override;

  // CoreStack overrides.
  bool Initialize() override;
  bool SetAdapterName(const std::string& name) override;
  bool SetClassicDiscoverable() override;
  const void* GetInterface(const char* profile) override;

 private:
  // Our libhardware handle.
  bluetooth_device_t *adapter_;

  // Common Bluetooth interface handle.
  const bt_interface_t *hal_;

  DISALLOW_COPY_AND_ASSIGN(CoreStackImpl);
};

CoreStackImpl::CoreStackImpl() : adapter_(nullptr), hal_(nullptr) {
  std::lock_guard<std::mutex> lock(mutex);
  // TODO(icoolidge): DCHECK(!instantiated);
  instantiated = true;
}

bool CoreStackImpl::Initialize() {
  std::unique_lock<std::mutex> lock(mutex);

  // Load the bluetooth module.
  const hw_module_t *module;
  int status = hal_util_load_bt_library(&module);
  if (status) {
    LOG_ERROR(LOG_TAG, "Error getting bluetooth module");
    return false;
  }

  // Open the bluetooth device.
  hw_device_t *device;
  status = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
  if (status) {
    LOG_ERROR(LOG_TAG, "Error opening bluetooth module");
    return false;
  }

  // TODO(icoolidge): Audit initialization and teardown.
  adapter_ = reinterpret_cast<bluetooth_device_t *>(device);
  hal_ = adapter_->get_bluetooth_interface();

  // Bind module callbacks to local handlers.
  status = hal_->init(&bt_callbacks);
  if (status != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Error binding callbacks");
    return false;
  }

  status = hal_->set_os_callouts(&callouts);
  if (status != BT_STATUS_SUCCESS) {
    LOG_ERROR(LOG_TAG, "Error binding OS callbacks");
    return false;
  }

  status = hal_->enable();
  if (status) {
    LOG_ERROR(LOG_TAG, "Enable failed: %d", status);
    return false;
  }

  synchronize.wait(lock);
  LOG_INFO(LOG_TAG, "%s", "CoreStackImpl::Initialize success");
  return true;
}

bool CoreStackImpl::SetAdapterName(const std::string &name) {
  bt_bdname_t n;
  snprintf(reinterpret_cast<char *>(n.name), sizeof(n.name), "%s",
           name.c_str());
  bt_property_t prop;
  prop.len = sizeof(n);
  prop.val = &n;
  prop.type = BT_PROPERTY_BDNAME;

  std::unique_lock<std::mutex> lock(mutex);

  int status = hal_->set_adapter_property(&prop);
  if (status) {
    LOG_ERROR(LOG_TAG, "%s: prop change failed: %d", __func__, status);
    return false;
  }

  synchronize.wait(lock);
  return true;
}

bool CoreStackImpl::SetClassicDiscoverable() {
  bt_scan_mode_t mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
  bt_property_t disc;
  disc.len = sizeof(mode);
  disc.val = &mode;
  disc.type = BT_PROPERTY_ADAPTER_SCAN_MODE;

  std::unique_lock<std::mutex> lock(mutex);

  int status = hal_->set_adapter_property(&disc);
  if (status) {
    LOG_ERROR(LOG_TAG, "Prop change failed: %d", status);
    return false;
  }

  synchronize.wait(lock);
  return true;
}

const void* CoreStackImpl::GetInterface(const char *profile) {
  std::unique_lock<std::mutex> lock(mutex);
  // Get the interface to the GATT profile.
  const void *interface = hal_->get_profile_interface(profile);
  if (!interface) {
    LOG_ERROR(LOG_TAG, "Error getting %s interface", profile);
    return nullptr;
  }
  return interface;
}

CoreStackImpl::~CoreStackImpl() {
  // TODO(icoolidge): Disable bluetooth hardware, clean up library state.
  std::lock_guard<std::mutex> lock(mutex);
  instantiated = false;
}

// static
std::unique_ptr<CoreStack> CoreStack::Create() {
  return std::unique_ptr<CoreStack>(new CoreStackImpl());
}

}  // namespace bluetooth
