/*
 * Copyright 2020 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <cstdint>
#include <string>
#include <unordered_set>
#include <vector>

#include "stack/include/acl_api_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/btm_api_types.h"
#include "stack/include/hcidefs.h"
#include "stack/include/hcimsgs.h"
#include "types/bt_transport.h"
#include "types/hci_role.h"
#include "types/raw_address.h"

enum btm_acl_encrypt_state_t {
  BTM_ACL_ENCRYPT_STATE_IDLE = 0,
  BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF = 1,
  BTM_ACL_ENCRYPT_STATE_TEMP_FUNC = 2,
  BTM_ACL_ENCRYPT_STATE_ENCRYPT_ON = 3,
};

enum btm_acl_swkey_state_t {
  BTM_ACL_SWKEY_STATE_IDLE = 0,
  BTM_ACL_SWKEY_STATE_MODE_CHANGE = 1,
  BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF = 2,
  BTM_ACL_SWKEY_STATE_SWITCHING = 3,
  BTM_ACL_SWKEY_STATE_ENCRYPTION_ON = 4,
  BTM_ACL_SWKEY_STATE_IN_PROGRESS = 5,
};

/* Policy settings status */
typedef enum : uint16_t {
  HCI_DISABLE_ALL_LM_MODES = 0,
  HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH = (1u << 0),
  HCI_ENABLE_HOLD_MODE = (1u << 1),
  HCI_ENABLE_SNIFF_MODE = (1u << 2),
  HCI_ENABLE_PARK_MODE = (1u << 3),
} tLINK_POLICY_BITMASK;
typedef uint16_t tLINK_POLICY;

constexpr tLINK_POLICY kAllLinkPoliciesEnabled =
    (HCI_ENABLE_CENTRAL_PERIPHERAL_SWITCH | HCI_ENABLE_HOLD_MODE |
     HCI_ENABLE_SNIFF_MODE);

static const char* link_policy_string[] = {
    " role_switch ",
    " hold_mode ",
    " sniff_mode ",
    " park_mode ",
};

inline std::string link_policy_text(tLINK_POLICY policy) {
  std::ostringstream os;
  os << "0x" << loghex(static_cast<uint16_t>(policy)) << " :";
  std::string s = os.str();
  for (uint16_t i = 0; i < 4; i++) {
    if (policy & (0x1 << i)) s += link_policy_string[i];
  }
  return s;
}

// Power mode states.
// Used as both value and bitmask
enum : uint8_t {
  BTM_PM_ST_ACTIVE = HCI_MODE_ACTIVE,      // 0x00
  BTM_PM_ST_HOLD = HCI_MODE_HOLD,          // 0x01
  BTM_PM_ST_SNIFF = HCI_MODE_SNIFF,        // 0x02
  BTM_PM_ST_PARK = HCI_MODE_PARK,          // 0x03
  BTM_PM_ST_UNUSED,                        // 0x04
  BTM_PM_ST_PENDING = BTM_PM_STS_PENDING,  // 0x05
  BTM_PM_ST_INVALID = 0x7F,
  BTM_PM_STORED_MASK = 0x80, /* set this mask if the command is stored */
};
typedef uint8_t tBTM_PM_STATE;

inline std::string power_mode_state_text(tBTM_PM_STATE state) {
  std::string s =
      std::string((state & BTM_PM_STORED_MASK) ? "stored:" : "immediate:");
  switch (state & ~BTM_PM_STORED_MASK) {
    case BTM_PM_ST_ACTIVE:
      return s + std::string("active");
    case BTM_PM_ST_HOLD:
      return s + std::string("hold");
    case BTM_PM_ST_SNIFF:
      return s + std::string("sniff");
    case BTM_PM_ST_PARK:
      return s + std::string("park");
    case BTM_PM_ST_UNUSED:
      return s + std::string("WARN:UNUSED");
    case BTM_PM_ST_PENDING:
      return s + std::string("pending");
    case BTM_PM_ST_INVALID:
      return s + std::string("invalid");
    default:
      return s + std::string("UNKNOWN");
  }
}

namespace bluetooth {
namespace shim {
tBTM_STATUS BTM_SetPowerMode(uint16_t handle, const tBTM_PM_PWR_MD& new_mode);
tBTM_STATUS BTM_SetSsrParams(uint16_t handle, uint16_t max_lat,
                             uint16_t min_rmt_to, uint16_t min_loc_to);
void btm_pm_on_mode_change(tHCI_STATUS status, uint16_t handle,
                           tHCI_MODE hci_mode, uint16_t interval);
void btm_pm_on_sniff_subrating(tHCI_STATUS status, uint16_t handle,
                               uint16_t maximum_transmit_latency,
                               uint16_t maximum_receive_latency,
                               uint16_t minimum_remote_timeout,
                               uint16_t minimum_local_timeout);
}  // namespace shim
}  // namespace bluetooth

typedef struct {
  uint16_t max_xmit_latency;
  uint16_t max_recv_latency;
  uint16_t min_remote_timeout;
  uint16_t min_local_timeout;
} tSSR_PARAMS;

#define BTM_PM_REC_NOT_USED 0
typedef struct {
  tBTM_PM_STATUS_CBACK* cback =
      nullptr;      /* to notify the registered party of mode change event */
  uint8_t mask = 0; /* registered request mask. 0, if this entry is not used */
} tBTM_PM_RCB;

/* Structure returned with Role Switch information (in tBTM_CMPL_CB callback
 * function) in response to BTM_SwitchRoleToCentral call.
 */
typedef struct {
  RawAddress remote_bd_addr; /* Remote BD addr involved with the switch */
  tHCI_STATUS hci_status;    /* HCI status returned with the event */
  tHCI_ROLE role;            /* HCI_ROLE_CENTRAL or HCI_ROLE_PERIPHERAL */
} tBTM_ROLE_SWITCH_CMPL;

struct tBTM_PM_MCB {
  bool chg_ind = false;
  tBTM_PM_PWR_MD req_mode;
  tBTM_PM_PWR_MD set_mode;
  tBTM_PM_STATE state = BTM_PM_ST_ACTIVE;  // 0
  uint16_t interval = 0;
  uint16_t max_lat = 0;
  uint16_t min_loc_to = 0;
  uint16_t min_rmt_to = 0;
  void Init(RawAddress bda, uint16_t handle) {
    bda_ = bda;
    handle_ = handle;
  }
  RawAddress bda_;
  uint16_t handle_;
};

struct tACL_CONN {
  BD_FEATURES peer_le_features;
  bool peer_le_features_valid;
  BD_FEATURES peer_lmp_feature_pages[HCI_EXT_FEATURES_PAGE_MAX + 1];
  bool peer_lmp_feature_valid[HCI_EXT_FEATURES_PAGE_MAX + 1];

  RawAddress active_remote_addr;
  RawAddress conn_addr;
  RawAddress remote_addr;
  bool in_use{false};

 public:
  bool InUse() const { return in_use; }
  const RawAddress RemoteAddress() const { return remote_addr; }

  bool link_up_issued;
  tBT_TRANSPORT transport;
  bool is_transport_br_edr() const { return transport == BT_TRANSPORT_BR_EDR; }
  bool is_transport_ble() const { return transport == BT_TRANSPORT_LE; }
  bool is_transport_valid() const {
    return is_transport_ble() || is_transport_br_edr();
  }

  uint16_t flush_timeout_in_ticks;
  uint16_t hci_handle;
  tLINK_POLICY link_policy;

 public:
  uint16_t Handle() const { return hci_handle; }
  uint16_t link_super_tout;
  uint16_t pkt_types_mask;
  tBLE_ADDR_TYPE active_remote_addr_type;
  tBLE_ADDR_TYPE conn_addr_type;
  uint8_t disconnect_reason;

 private:
  btm_acl_encrypt_state_t encrypt_state_;

 public:
  void set_encryption_off() {
    if (encrypt_state_ != BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF) {
      btsnd_hcic_set_conn_encrypt(hci_handle, false);
      encrypt_state_ = BTM_ACL_ENCRYPT_STATE_ENCRYPT_OFF;
    }
  }
  void set_encryption_on() {
    if (encrypt_state_ != BTM_ACL_ENCRYPT_STATE_ENCRYPT_ON) {
      btsnd_hcic_set_conn_encrypt(hci_handle, true);
      encrypt_state_ = BTM_ACL_ENCRYPT_STATE_ENCRYPT_ON;
    }
  }
  void set_encryption_idle() { encrypt_state_ = BTM_ACL_ENCRYPT_STATE_IDLE; }

  void set_encryption_switching() {
    encrypt_state_ = BTM_ACL_ENCRYPT_STATE_TEMP_FUNC;
  }

 public:
  bool is_encrypted = false;
  tHCI_ROLE link_role;
  uint8_t switch_role_failed_attempts;

  tREMOTE_VERSION_INFO remote_version_info;

#define BTM_SEC_RS_NOT_PENDING 0 /* Role Switch not in progress */
#define BTM_SEC_RS_PENDING 1     /* Role Switch in progress */
#define BTM_SEC_DISC_PENDING 2   /* Disconnect is pending */
 private:
  uint8_t rs_disc_pending = BTM_SEC_RS_NOT_PENDING;
  friend struct StackAclBtmAcl;
  friend tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr,
                                    tBT_TRANSPORT transport);
  friend void acl_disconnect_after_role_switch(uint16_t conn_handle,
                                               tHCI_STATUS reason);
  friend void bluetooth::shim::btm_pm_on_mode_change(tHCI_STATUS status,
                                                     uint16_t handle,
                                                     tHCI_MODE hci_mode,
                                                     uint16_t interval);
  friend void btm_acl_encrypt_change(uint16_t handle, uint8_t status,
                                     uint8_t encr_enable);

 public:
  bool is_disconnect_pending() const {
    return rs_disc_pending == BTM_SEC_DISC_PENDING;
  }
  bool is_role_switch_pending() const {
    return rs_disc_pending == BTM_SEC_RS_PENDING;
  }

 private:
  uint8_t switch_role_state_;

 public:
  void reset_switch_role() { switch_role_state_ = BTM_ACL_SWKEY_STATE_IDLE; }
  void set_switch_role_changing() {
    switch_role_state_ = BTM_ACL_SWKEY_STATE_MODE_CHANGE;
  }
  void set_switch_role_encryption_off() {
    switch_role_state_ = BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF;
  }
  void set_switch_role_encryption_on() {
    switch_role_state_ = BTM_ACL_SWKEY_STATE_ENCRYPTION_ON;
  }
  void set_switch_role_in_progress() {
    switch_role_state_ = BTM_ACL_SWKEY_STATE_IN_PROGRESS;
  }
  void set_switch_role_switching() {
    switch_role_state_ = BTM_ACL_SWKEY_STATE_SWITCHING;
  }

  bool is_switch_role_idle() const {
    return switch_role_state_ == BTM_ACL_SWKEY_STATE_IDLE;
  }
  bool is_switch_role_encryption_off() const {
    return switch_role_state_ == BTM_ACL_SWKEY_STATE_ENCRYPTION_OFF;
  }
  bool is_switch_role_encryption_on() const {
    return switch_role_state_ == BTM_ACL_SWKEY_STATE_ENCRYPTION_ON;
  }
  bool is_switch_role_switching() const {
    return switch_role_state_ == BTM_ACL_SWKEY_STATE_SWITCHING;
  }
  bool is_switch_role_in_progress() const {
    return switch_role_state_ == BTM_ACL_SWKEY_STATE_IN_PROGRESS;
  }
  bool is_switch_role_mode_change() const {
    return switch_role_state_ == BTM_ACL_SWKEY_STATE_MODE_CHANGE;
  }
  bool is_switch_role_switching_or_in_progress() const {
    return is_switch_role_switching() || is_switch_role_in_progress();
  }

  friend void DumpsysL2cap(int fd);

 public:
  uint8_t sca; /* Sleep clock accuracy */

  void Reset();

  struct tPolicy {
    tBTM_PM_MODE Mode() const { return this->mode.mode_; }
    struct {
      bool IsPending() const { return pending_ != BTM_PM_MD_UNKNOWN; }
      tBTM_PM_MODE Pending() const { return pending_; }
      uint16_t Interval() const { return interval_; }

     private:
      tBTM_PM_MODE mode_{BTM_PM_MD_ACTIVE};
      tBTM_PM_MODE pending_{BTM_PM_MD_UNKNOWN};
      uint16_t interval_{0};
      friend tBTM_STATUS bluetooth::shim::BTM_SetPowerMode(
          uint16_t, const tBTM_PM_PWR_MD& new_mode);
      friend void bluetooth::shim::btm_pm_on_mode_change(tHCI_STATUS status,
                                                         uint16_t handle,
                                                         tHCI_MODE hci_mode,
                                                         uint16_t interval);
      friend void tACL_CONN::Reset();
      friend tBTM_PM_MODE tACL_CONN::tPolicy::Mode() const;
    } mode;

    hci_role_t Role() const { return this->role.role_; }
    struct {
      unsigned RoleSwitchFailedCount() const { return role_switch_failed_cnt_; }

     private:
      hci_role_t role_{HCI_ROLE_CENTRAL};
      unsigned role_switch_failed_cnt_{0};
      friend void tACL_CONN::Reset();
      friend hci_role_t tACL_CONN::tPolicy::Role() const;
    } role;

    struct {
      bool IsPending() const { return pending_; }

     private:
      bool pending_{false};
      friend tBTM_STATUS bluetooth::shim::BTM_SetSsrParams(uint16_t handle,
                                                           uint16_t max_lat,
                                                           uint16_t min_rmt_to,
                                                           uint16_t min_loc_to);
      friend void bluetooth::shim::btm_pm_on_sniff_subrating(
          tHCI_STATUS status, uint16_t handle,
          uint16_t maximum_transmit_latency, uint16_t maximum_receive_latency,
          uint16_t minimum_remote_timeout, uint16_t minimum_local_timeout);
      friend void tACL_CONN::Reset();
    } sniff_subrating;

    tLINK_POLICY Settings() const { return settings_; }

   private:
    tLINK_POLICY settings_{kAllLinkPoliciesEnabled};
    friend void btm_set_link_policy(tACL_CONN* conn, tLINK_POLICY policy);
    friend void tACL_CONN::Reset();
  } policy;
};

struct controller_t;

/****************************************************
 **      ACL Management API
 ****************************************************/
constexpr uint16_t kDefaultPacketTypeMask =
    HCI_PKT_TYPES_MASK_DH1 | HCI_PKT_TYPES_MASK_DM1 | HCI_PKT_TYPES_MASK_DH3 |
    HCI_PKT_TYPES_MASK_DM3 | HCI_PKT_TYPES_MASK_DH5 | HCI_PKT_TYPES_MASK_DM5;

struct tACL_CB {
 private:
  friend uint8_t btm_handle_to_acl_index(uint16_t hci_handle);
  friend void btm_acl_device_down(void);
  friend void btm_acl_encrypt_change(uint16_t handle, uint8_t status,
                                     uint8_t encr_enable);

  friend void DumpsysL2cap(int fd);
  friend void DumpsysAcl(int fd);
  friend struct StackAclBtmAcl;

  tACL_CONN acl_db[MAX_L2CAP_LINKS];
  tBTM_ROLE_SWITCH_CMPL switch_role_ref_data;
  uint16_t btm_acl_pkt_types_supported = kDefaultPacketTypeMask;
  uint16_t btm_def_link_policy;
  tHCI_STATUS acl_disc_reason = HCI_ERR_UNDEFINED;

 public:
  void SetDefaultPacketTypeMask(uint16_t packet_type_mask) {
    btm_acl_pkt_types_supported = packet_type_mask;
  }

  tHCI_STATUS get_disconnect_reason() const { return acl_disc_reason; }
  void set_disconnect_reason(tHCI_STATUS reason) { acl_disc_reason = reason; }
  uint16_t DefaultPacketTypes() const { return btm_acl_pkt_types_supported; }
  uint16_t DefaultLinkPolicy() const { return btm_def_link_policy; }

  struct {
    std::vector<tBTM_PM_STATUS_CBACK*> clients;
  } link_policy;

  unsigned NumberOfActiveLinks() const {
    unsigned cnt = 0;
    for (int i = 0; i < MAX_L2CAP_LINKS; i++) {
      if (acl_db[i].InUse()) ++cnt;
    }
    return cnt;
  }

 private:
  std::unordered_set<RawAddress> ignore_auto_connect_after_disconnect_set_;

 public:
  void AddToIgnoreAutoConnectAfterDisconnect(const RawAddress& bd_addr);
  bool CheckAndClearIgnoreAutoConnectAfterDisconnect(const RawAddress& bd_addr);
  void ClearAllIgnoreAutoConnectAfterDisconnect();
};
