/*
 * Copyright 2019 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.
 */

#include "hci/acl_manager.h"

#include <atomic>
#include <future>
#include <set>

#include "common/bidi_queue.h"
#include "hci/acl_manager/classic_impl.h"
#include "hci/acl_manager/connection_management_callbacks.h"
#include "hci/acl_manager/le_acl_connection.h"
#include "hci/acl_manager/le_impl.h"
#include "hci/acl_manager/round_robin_scheduler.h"
#include "hci/controller.h"
#include "hci/hci_layer.h"
#include "hci_acl_manager_generated.h"
#include "security/security_module.h"
#include "storage/storage_module.h"

namespace bluetooth {
namespace hci {

constexpr uint16_t kQualcommDebugHandle = 0xedc;

using acl_manager::AclConnection;
using common::Bind;
using common::BindOnce;

using acl_manager::classic_impl;
using acl_manager::ClassicAclConnection;
using acl_manager::ConnectionCallbacks;

using acl_manager::le_impl;
using acl_manager::LeAclConnection;
using acl_manager::LeConnectionCallbacks;

using acl_manager::RoundRobinScheduler;

struct AclManager::impl {
  impl(const AclManager& acl_manager) : acl_manager_(acl_manager) {}

  void Start() {
    hci_layer_ = acl_manager_.GetDependency<HciLayer>();
    handler_ = acl_manager_.GetHandler();
    controller_ = acl_manager_.GetDependency<Controller>();
    round_robin_scheduler_ = new RoundRobinScheduler(handler_, controller_, hci_layer_->GetAclQueueEnd());

    hci_queue_end_ = hci_layer_->GetAclQueueEnd();
    hci_queue_end_->RegisterDequeue(
        handler_, common::Bind(&impl::dequeue_and_route_acl_packet_to_connection, common::Unretained(this)));
    bool crash_on_unknown_handle = false;
    classic_impl_ =
        new classic_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, crash_on_unknown_handle);
    le_impl_ = new le_impl(hci_layer_, controller_, handler_, round_robin_scheduler_, crash_on_unknown_handle);
  }

  void Stop() {
    delete le_impl_;
    delete classic_impl_;
    hci_queue_end_->UnregisterDequeue();
    delete round_robin_scheduler_;
    if (enqueue_registered_.exchange(false)) {
      hci_queue_end_->UnregisterEnqueue();
    }
    hci_queue_end_ = nullptr;
    handler_ = nullptr;
    hci_layer_ = nullptr;
  }

  // Invoked from some external Queue Reactable context 2
  void dequeue_and_route_acl_packet_to_connection() {
    auto packet = hci_queue_end_->TryDequeue();
    ASSERT(packet != nullptr);
    if (!packet->IsValid()) {
      LOG_INFO("Dropping invalid packet of size %zu", packet->size());
      return;
    }
    uint16_t handle = packet->GetHandle();
    if (handle == kQualcommDebugHandle) {
      return;
    }
    auto connection_pair = classic_impl_->acl_connections_.find(handle);
    if (connection_pair != classic_impl_->acl_connections_.end()) {
      connection_pair->second.assembler_.on_incoming_packet(*packet);
    } else {
      auto le_connection_pair = le_impl_->le_acl_connections_.find(handle);
      if (le_connection_pair == le_impl_->le_acl_connections_.end()) {
        LOG_INFO("Dropping packet of size %zu to unknown connection 0x%0hx", packet->size(), handle);
        return;
      }
      le_connection_pair->second.assembler_.on_incoming_packet(*packet);
    }
  }

  void Dump(
      std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const;

  const AclManager& acl_manager_;

  classic_impl* classic_impl_ = nullptr;
  le_impl* le_impl_ = nullptr;
  os::Handler* handler_ = nullptr;
  Controller* controller_ = nullptr;
  HciLayer* hci_layer_ = nullptr;
  RoundRobinScheduler* round_robin_scheduler_ = nullptr;
  common::BidiQueueEnd<AclBuilder, AclView>* hci_queue_end_ = nullptr;
  std::atomic_bool enqueue_registered_ = false;
  uint16_t default_link_policy_settings_ = 0xffff;
};

AclManager::AclManager() : pimpl_(std::make_unique<impl>(*this)) {}

void AclManager::RegisterCallbacks(ConnectionCallbacks* callbacks, os::Handler* handler) {
  ASSERT(callbacks != nullptr && handler != nullptr);
  GetHandler()->Post(common::BindOnce(&classic_impl::handle_register_callbacks,
                                      common::Unretained(pimpl_->classic_impl_), common::Unretained(callbacks),
                                      common::Unretained(handler)));
}

void AclManager::UnregisterCallbacks(ConnectionCallbacks* callbacks, std::promise<void> promise) {
  ASSERT(callbacks != nullptr);
  CallOn(
      pimpl_->classic_impl_,
      &classic_impl::handle_unregister_callbacks,
      common::Unretained(callbacks),
      std::move(promise));
}

void AclManager::RegisterLeCallbacks(LeConnectionCallbacks* callbacks, os::Handler* handler) {
  ASSERT(callbacks != nullptr && handler != nullptr);
  CallOn(
      pimpl_->le_impl_,
      &le_impl::handle_register_le_callbacks,
      common::Unretained(callbacks),
      common::Unretained(handler));
}

void AclManager::UnregisterLeCallbacks(LeConnectionCallbacks* callbacks, std::promise<void> promise) {
  ASSERT(callbacks != nullptr);
  CallOn(pimpl_->le_impl_, &le_impl::handle_unregister_le_callbacks, common::Unretained(callbacks), std::move(promise));
}

void AclManager::CreateConnection(Address address) {
  CallOn(pimpl_->classic_impl_, &classic_impl::create_connection, address);
}

void AclManager::CreateLeConnection(AddressWithType address_with_type, bool is_direct) {
  CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true, is_direct);
}

void AclManager::SetLeSuggestedDefaultDataParameters(uint16_t octets, uint16_t time) {
  CallOn(pimpl_->le_impl_, &le_impl::set_le_suggested_default_data_parameters, octets, time);
}

void AclManager::SetPrivacyPolicyForInitiatorAddress(
    LeAddressManager::AddressPolicy address_policy,
    AddressWithType fixed_address,
    std::chrono::milliseconds minimum_rotation_time,
    std::chrono::milliseconds maximum_rotation_time) {
  crypto_toolbox::Octet16 rotation_irk{};
  auto irk = GetDependency<storage::StorageModule>()->GetAdapterConfig().GetLeIdentityResolvingKey();
  if (irk.has_value()) {
    rotation_irk = irk->bytes;
  }
  CallOn(
      pimpl_->le_impl_,
      &le_impl::set_privacy_policy_for_initiator_address,
      address_policy,
      fixed_address,
      rotation_irk,
      minimum_rotation_time,
      maximum_rotation_time);
}

// TODO(jpawlowski): remove once we have config file abstraction in cert tests
void AclManager::SetPrivacyPolicyForInitiatorAddressForTest(
    LeAddressManager::AddressPolicy address_policy,
    AddressWithType fixed_address,
    crypto_toolbox::Octet16 rotation_irk,
    std::chrono::milliseconds minimum_rotation_time,
    std::chrono::milliseconds maximum_rotation_time) {
  CallOn(
      pimpl_->le_impl_,
      &le_impl::set_privacy_policy_for_initiator_address_for_test,
      address_policy,
      fixed_address,
      rotation_irk,
      minimum_rotation_time,
      maximum_rotation_time);
}

void AclManager::CancelConnect(Address address) {
  CallOn(pimpl_->classic_impl_, &classic_impl::cancel_connect, address);
}

void AclManager::CancelLeConnect(AddressWithType address_with_type) {
  CallOn(pimpl_->le_impl_, &le_impl::cancel_connect, address_with_type);
}

void AclManager::AddDeviceToConnectList(AddressWithType address_with_type) {
  CallOn(pimpl_->le_impl_, &le_impl::add_device_to_connect_list, address_with_type);
}

void AclManager::AddDeviceToResolvingList(
    AddressWithType address_with_type,
    const std::array<uint8_t, 16>& peer_irk,
    const std::array<uint8_t, 16>& local_irk) {
  CallOn(pimpl_->le_impl_, &le_impl::add_device_to_resolving_list, address_with_type, peer_irk, local_irk);
}

void AclManager::RemoveDeviceFromConnectList(AddressWithType address_with_type) {
  CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_connect_list, address_with_type);
}

void AclManager::RemoveDeviceFromResolvingList(AddressWithType address_with_type) {
  CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_resolving_list, address_with_type);
}

void AclManager::CentralLinkKey(KeyFlag key_flag) {
  CallOn(pimpl_->classic_impl_, &classic_impl::central_link_key, key_flag);
}

void AclManager::SwitchRole(Address address, Role role) {
  CallOn(pimpl_->classic_impl_, &classic_impl::switch_role, address, role);
}

uint16_t AclManager::ReadDefaultLinkPolicySettings() {
  ASSERT_LOG(pimpl_->default_link_policy_settings_ != 0xffff, "Settings were never written");
  return pimpl_->default_link_policy_settings_;
}

void AclManager::WriteDefaultLinkPolicySettings(uint16_t default_link_policy_settings) {
  pimpl_->default_link_policy_settings_ = default_link_policy_settings;
  CallOn(pimpl_->classic_impl_, &classic_impl::write_default_link_policy_settings, default_link_policy_settings);
}

void AclManager::OnAdvertisingSetTerminated(ErrorCode status, uint16_t conn_handle, hci::AddressWithType adv_address) {
  if (status == ErrorCode::SUCCESS) {
    CallOn(pimpl_->le_impl_, &le_impl::UpdateLocalAddress, conn_handle, adv_address);
  }
}

void AclManager::SetSecurityModule(security::SecurityModule* security_module) {
  CallOn(pimpl_->classic_impl_, &classic_impl::set_security_module, security_module);
}

LeAddressManager* AclManager::GetLeAddressManager() {
  return pimpl_->le_impl_->le_address_manager_;
}

uint16_t AclManager::HACK_GetHandle(Address address) {
  return pimpl_->classic_impl_->HACK_get_handle(address);
}

uint16_t AclManager::HACK_GetLeHandle(Address address) {
  return pimpl_->le_impl_->HACK_get_handle(address);
}

void AclManager::HACK_SetNonAclDisconnectCallback(std::function<void(uint16_t, uint8_t)> callback) {
  pimpl_->classic_impl_->HACK_SetNonAclDisconnectCallback(callback);
}

void AclManager::HACK_SetAclTxPriority(uint8_t handle, bool high_priority) {
  CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority);
}

void AclManager::ListDependencies(ModuleList* list) {
  list->add<HciLayer>();
  list->add<Controller>();
  list->add<storage::StorageModule>();
}

void AclManager::Start() {
  pimpl_->Start();
}

void AclManager::Stop() {
  pimpl_->Stop();
}

std::string AclManager::ToString() const {
  return "Acl Manager";
}

const ModuleFactory AclManager::Factory = ModuleFactory([]() { return new AclManager(); });

AclManager::~AclManager() = default;

void AclManager::impl::Dump(
    std::promise<flatbuffers::Offset<AclManagerData>> promise, flatbuffers::FlatBufferBuilder* fb_builder) const {
  auto title = fb_builder->CreateString("----- Acl Manager Dumpsys -----");
  AclManagerDataBuilder builder(*fb_builder);
  builder.add_title(title);
  flatbuffers::Offset<AclManagerData> dumpsys_data = builder.Finish();
  promise.set_value(dumpsys_data);
}

DumpsysDataFinisher AclManager::GetDumpsysData(flatbuffers::FlatBufferBuilder* fb_builder) const {
  ASSERT(fb_builder != nullptr);

  std::promise<flatbuffers::Offset<AclManagerData>> promise;
  auto future = promise.get_future();
  pimpl_->Dump(std::move(promise), fb_builder);

  auto dumpsys_data = future.get();

  return [dumpsys_data](DumpsysDataBuilder* dumpsys_builder) {
    dumpsys_builder->add_hci_acl_manager_dumpsys_data(dumpsys_data);
  };
}

}  // namespace hci
}  // namespace bluetooth
