/******************************************************************************
 *
 *  Copyright 2014 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_stack_manager"

#include "btif/include/stack_manager.h"

#include <hardware/bluetooth.h>
#if defined(STATIC_LIBBLUETOOTH)
#include <cstdlib>
#include <cstring>
#endif

#include "btcore/include/module.h"
#include "btcore/include/osi_module.h"
#include "btif_api.h"
#include "btif_common.h"
#include "common/message_loop_thread.h"
#include "hci/include/btsnoop.h"
#include "main/shim/shim.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "osi/include/semaphore.h"
#include "stack/include/acl_api.h"
#include "stack/include/btm_client_interface.h"
#include "stack/include/btu.h"

// Temp includes
#include "bt_utils.h"
#include "bta/sys/bta_sys.h"
#include "btif_config.h"
#include "btif_profile_queue.h"
#include "internal_include/bt_target.h"
#include "stack/include/gatt_api.h"
#include "stack/include/l2c_api.h"
#include "stack/include/port_api.h"
#include "stack/sdp/sdpint.h"
#if (BNEP_INCLUDED == TRUE)
#include "stack/include/bnep_api.h"
#endif
#include "stack/include/gap_api.h"
#if (PAN_INCLUDED == TRUE)
#include "stack/include/pan_api.h"
#endif
#include "stack/include/a2dp_api.h"
#include "stack/include/avrc_api.h"
#if (HID_HOST_INCLUDED == TRUE)
#include "stack/include/hidh_api.h"
#endif
#include "stack/include/smp_api.h"
#include "bta_ar_api.h"
#include "bta/sys/bta_sys_int.h"
#include "bta_dm_int.h"
#include "btif/include/btif_pan.h"
#include "btif/include/btif_sock.h"
#include "device/include/interop.h"
#include "internal_include/stack_config.h"
#include "main/shim/controller.h"

// Validate or respond to various conditional compilation flags

#if BLE_PRIVACY_SPT != TRUE
// Once BLE_PRIVACY_SPT is no longer exposed via bt_target.h
// this check and error statement may be removed.
#warning \
    "#define BLE_PRIVACY_SPT FALSE preprocessor compilation flag is unsupported"
#warning \
    "  To disable LE privacy for a device use: #define BLE_LOCAL_PRIVACY_ENABLED FALSE"
#error "*** Conditional Compilation Directive error"
#endif

#if SDP_RAW_DATA_INCLUDED != TRUE
// Once SDP_RAW_DATA_INCLUDED is no longer exposed via bt_target.h
// this check and error statement may be removed.
#warning \
    "#define SDP_RAW_DATA_INCLUDED preprocessor compilation flag is unsupported"
#error "*** Conditional Compilation Directive error"
#endif

// Once BTA_PAN_INCLUDED is no longer exposed via bt_target.h
// this check and error statement may be removed.
static_assert(
    BTA_PAN_INCLUDED,
    "#define BTA_PAN_INCLUDED preprocessor compilation flag is unsupported"
    "  Pan profile is always included in the bluetooth stack"
    "*** Conditional Compilation Directive error");

// Once PAN_SUPPORTS_ROLE_NAP is no longer exposed via bt_target.h
// this check and error statement may be removed.
static_assert(
    PAN_SUPPORTS_ROLE_NAP,
    "#define PAN_SUPPORTS_ROLE_NAP preprocessor compilation flag is unsupported"
    "  Pan profile always supports network access point in the bluetooth stack"
    "*** Conditional Compilation Directive error");

// Once PAN_SUPPORTS_ROLE_PANU is no longer exposed via bt_target.h
// this check and error statement may be removed.
static_assert(
    PAN_SUPPORTS_ROLE_PANU,
    "#define PAN_SUPPORTS_ROLE_PANU preprocessor compilation flag is "
    "unsupported"
    "  Pan profile always supports user as a client in the bluetooth stack"
    "*** Conditional Compilation Directive error");

void main_thread_shut_down();
void main_thread_start_up();
void BTA_dm_on_hw_on();
void BTA_dm_on_hw_off();

using bluetooth::common::MessageLoopThread;

static MessageLoopThread management_thread("bt_stack_manager_thread");

// If initialized, any of the bluetooth API functions can be called.
// (e.g. turning logging on and off, enabling/disabling the stack, etc)
static bool stack_is_initialized;
// If running, the stack is fully up and able to bluetooth.
static bool stack_is_running;

static void event_init_stack(void* context);
static void event_start_up_stack(void* context);
static void event_shut_down_stack(void* context);
static void event_clean_up_stack(void* context);

static void event_signal_stack_up(void* context);
static void event_signal_stack_down(void* context);

// Unvetted includes/imports, etc which should be removed or vetted in the
// future
static future_t* hack_future;
// End unvetted section

// Interface functions

static void init_stack() {
  // This is a synchronous process. Post it to the thread though, so
  // state modification only happens there. Using the thread to perform
  // all stack operations ensures that the operations are done serially
  // and do not overlap.
  semaphore_t* semaphore = semaphore_new(0);
  management_thread.DoInThread(FROM_HERE,
                               base::Bind(event_init_stack, semaphore));
  semaphore_wait(semaphore);
  semaphore_free(semaphore);
}

static void start_up_stack_async() {
  management_thread.DoInThread(FROM_HERE,
                               base::Bind(event_start_up_stack, nullptr));
}

static void shut_down_stack_async() {
  management_thread.DoInThread(FROM_HERE,
                               base::Bind(event_shut_down_stack, nullptr));
}

static void clean_up_stack() {
  // This is a synchronous process. Post it to the thread though, so
  // state modification only happens there.
  semaphore_t* semaphore = semaphore_new(0);
  management_thread.DoInThread(FROM_HERE,
                               base::Bind(event_clean_up_stack, semaphore));
  semaphore_wait(semaphore);
  semaphore_free(semaphore);
  management_thread.ShutDown();
}

static bool get_stack_is_running() { return stack_is_running; }

// Internal functions

#ifdef STATIC_LIBBLUETOOTH
extern const module_t bt_utils_module;
extern const module_t bte_logmsg_module;
extern const module_t btif_config_module;
extern const module_t btsnoop_module;
extern const module_t bt_utils_module;
extern const module_t gd_controller_module;
extern const module_t gd_idle_module;
extern const module_t gd_shim_module;
extern const module_t hci_module;
extern const module_t interop_module;
extern const module_t osi_module;
extern const module_t stack_config_module;

struct module_lookup {
  const char* name;
  const module_t* module;
};

const struct module_lookup module_table[] = {
    {BTE_LOGMSG_MODULE, &bte_logmsg_module},
    {BTIF_CONFIG_MODULE, &btif_config_module},
    {BTSNOOP_MODULE, &btsnoop_module},
    {BT_UTILS_MODULE, &bt_utils_module},
    {GD_CONTROLLER_MODULE, &gd_controller_module},
    {GD_IDLE_MODULE, &gd_idle_module},
    {GD_SHIM_MODULE, &gd_shim_module},
    {INTEROP_MODULE, &interop_module},
    {OSI_MODULE, &osi_module},
    {STACK_CONFIG_MODULE, &stack_config_module},
    {NULL, NULL},
};

inline const module_t* get_local_module(const char* name) {
  size_t len = strlen(name);

  for (const struct module_lookup* l = module_table; l->module; l++) {
    if (strncmp(l->name, name, len) == 0) {
      return l->module;
    }
  }

  LOG_ALWAYS_FATAL("Cannot find module %s, aborting", name);
  return nullptr;
}
#else
inline const module_t* get_local_module(const char* name) {
  return get_module(name);
}
#endif

// Synchronous function to initialize the stack
static void event_init_stack(void* context) {
  semaphore_t* semaphore = (semaphore_t*)context;

  LOG_INFO("is initializing the stack");

  if (stack_is_initialized) {
    LOG_INFO("found the stack already in initialized state");
  } else {
    module_management_start();

    module_init(get_local_module(OSI_MODULE));
    module_init(get_local_module(BT_UTILS_MODULE));
    if (bluetooth::shim::is_any_gd_enabled()) {
      module_start_up(get_local_module(GD_IDLE_MODULE));
    }
    module_init(get_local_module(BTIF_CONFIG_MODULE));
    btif_init_bluetooth();

    module_init(get_local_module(INTEROP_MODULE));
    bte_main_init();
    module_init(get_local_module(STACK_CONFIG_MODULE));

    // stack init is synchronous, so no waiting necessary here
    stack_is_initialized = true;
  }

  LOG_INFO("finished");

  if (semaphore) semaphore_post(semaphore);
}

static void ensure_stack_is_initialized() {
  if (!stack_is_initialized) {
    LOG_WARN("%s found the stack was uninitialized. Initializing now.",
             __func__);
    // No semaphore needed since we are calling it directly
    event_init_stack(nullptr);
  }
}

// Synchronous function to start up the stack
static void event_start_up_stack(UNUSED_ATTR void* context) {
  if (stack_is_running) {
    LOG_INFO("%s stack already brought up", __func__);
    return;
  }

  ensure_stack_is_initialized();

  LOG_INFO("%s is bringing up the stack", __func__);
  future_t* local_hack_future = future_new();
  hack_future = local_hack_future;

  if (bluetooth::shim::is_any_gd_enabled()) {
    LOG_INFO("%s Gd shim module enabled", __func__);
    module_shut_down(get_local_module(GD_IDLE_MODULE));
    module_start_up(get_local_module(GD_SHIM_MODULE));
    module_start_up(get_local_module(BTIF_CONFIG_MODULE));
  } else {
    module_start_up(get_local_module(BTIF_CONFIG_MODULE));
    module_start_up(get_local_module(BTSNOOP_MODULE));
  }

  get_btm_client_interface().lifecycle.btm_init();
  l2c_init();
  sdp_init();
  gatt_init();
  SMP_Init();
  get_btm_client_interface().lifecycle.btm_ble_init();

  RFCOMM_Init();
#if (BNEP_INCLUDED == TRUE)
  BNEP_Init();
#if (PAN_INCLUDED == TRUE)
  PAN_Init();
#endif /* PAN */
#endif /* BNEP Included */
  A2DP_Init();
  AVRC_Init();
  GAP_Init();
#if (HID_HOST_INCLUDED == TRUE)
  HID_HostInit();
#endif

  bta_sys_init();
  bta_ar_init();
  module_init(get_local_module(BTE_LOGMSG_MODULE));

  main_thread_start_up();

  btif_init_ok();
  BTA_dm_init();
  bta_dm_enable(bte_dm_evt);

  bta_set_forward_hw_failures(true);
  btm_acl_device_down();
  CHECK(module_start_up(get_local_module(GD_CONTROLLER_MODULE)));
  BTM_reset_complete();

  BTA_dm_on_hw_on();

  if (future_await(local_hack_future) != FUTURE_SUCCESS) {
    LOG_ERROR("%s failed to start up the stack", __func__);
    stack_is_running = true;  // So stack shutdown actually happens
    event_shut_down_stack(nullptr);
    return;
  }

  stack_is_running = true;
  LOG_INFO("%s finished", __func__);
  do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_up, nullptr));
}

// Synchronous function to shut down the stack
static void event_shut_down_stack(UNUSED_ATTR void* context) {
  if (!stack_is_running) {
    LOG_INFO("%s stack is already brought down", __func__);
    return;
  }

  LOG_INFO("%s is bringing down the stack", __func__);
  future_t* local_hack_future = future_new();
  hack_future = local_hack_future;
  stack_is_running = false;

  do_in_main_thread(FROM_HERE, base::Bind(&btm_ble_multi_adv_cleanup));

  btif_dm_on_disable();
  btif_sock_cleanup();
  btif_pan_cleanup();

  do_in_main_thread(FROM_HERE, base::Bind(bta_dm_disable));

  future_await(local_hack_future);
  local_hack_future = future_new();
  hack_future = local_hack_future;

  bta_sys_disable();
  bta_set_forward_hw_failures(false);
  BTA_dm_on_hw_off();

  module_shut_down(get_local_module(BTIF_CONFIG_MODULE));

  future_await(local_hack_future);

  main_thread_shut_down();

  module_clean_up(get_local_module(BTE_LOGMSG_MODULE));

  gatt_free();
  l2c_free();
  sdp_free();
  get_btm_client_interface().lifecycle.btm_ble_free();
  get_btm_client_interface().lifecycle.btm_free();

  if (bluetooth::shim::is_any_gd_enabled()) {
    LOG_INFO("%s Gd shim module disabled", __func__);
    module_shut_down(get_local_module(GD_SHIM_MODULE));
    module_start_up(get_local_module(GD_IDLE_MODULE));
  } else {
    module_shut_down(get_local_module(BTSNOOP_MODULE));
  }

  hack_future = future_new();
  do_in_jni_thread(FROM_HERE, base::Bind(event_signal_stack_down, nullptr));
  future_await(hack_future);
  LOG_INFO("%s finished", __func__);
}

static void ensure_stack_is_not_running() {
  if (stack_is_running) {
    LOG_WARN("%s found the stack was still running. Bringing it down now.",
             __func__);
    event_shut_down_stack(nullptr);
  }
}

// Synchronous function to clean up the stack
static void event_clean_up_stack(void* context) {
  if (!stack_is_initialized) {
    LOG_INFO("%s found the stack already in a clean state", __func__);
    goto cleanup;
  }

  ensure_stack_is_not_running();

  LOG_INFO("%s is cleaning up the stack", __func__);
  stack_is_initialized = false;

  btif_cleanup_bluetooth();

  module_clean_up(get_local_module(STACK_CONFIG_MODULE));
  module_clean_up(get_local_module(INTEROP_MODULE));

  module_clean_up(get_local_module(BTIF_CONFIG_MODULE));
  module_clean_up(get_local_module(BT_UTILS_MODULE));
  module_clean_up(get_local_module(OSI_MODULE));
  module_shut_down(get_local_module(GD_IDLE_MODULE));
  module_management_stop();
  LOG_INFO("%s finished", __func__);

cleanup:;
  semaphore_t* semaphore = (semaphore_t*)context;
  if (semaphore) semaphore_post(semaphore);
}

static void event_signal_stack_up(UNUSED_ATTR void* context) {
  // Notify BTIF connect queue that we've brought up the stack. It's
  // now time to dispatch all the pending profile connect requests.
  btif_queue_connect_next();
  invoke_adapter_state_changed_cb(BT_STATE_ON);
}

static void event_signal_stack_down(UNUSED_ATTR void* context) {
  invoke_adapter_state_changed_cb(BT_STATE_OFF);
  future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
}

static void ensure_manager_initialized() {
  if (management_thread.IsRunning()) return;

  management_thread.StartUp();
  if (!management_thread.IsRunning()) {
    LOG_ERROR("%s unable to start stack management thread", __func__);
    return;
  }
}

static const stack_manager_t interface = {init_stack, start_up_stack_async,
                                          shut_down_stack_async, clean_up_stack,
                                          get_stack_is_running};

const stack_manager_t* stack_manager_get_interface() {
  ensure_manager_initialized();
  return &interface;
}

future_t* stack_manager_get_hack_future() { return hack_future; }
