// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "bredr_connection_manager.h"

#include <zircon/assert.h>

#include "garnet/drivers/bluetooth/lib/common/log.h"
#include "garnet/drivers/bluetooth/lib/gap/remote_device_cache.h"
#include "garnet/drivers/bluetooth/lib/hci/connection.h"
#include "garnet/drivers/bluetooth/lib/hci/hci_constants.h"
#include "garnet/drivers/bluetooth/lib/hci/sequential_command_runner.h"
#include "garnet/drivers/bluetooth/lib/hci/transport.h"

namespace btlib {
namespace gap {

using common::HostError;

namespace {

void SetPageScanEnabled(bool enabled, fxl::RefPtr<hci::Transport> hci,
                        async_dispatcher_t* dispatcher,
                        hci::StatusCallback cb) {
  ZX_DEBUG_ASSERT(cb);
  auto read_enable = hci::CommandPacket::New(hci::kReadScanEnable);
  auto finish_enable_cb = [enabled, dispatcher, hci, finish_cb = std::move(cb)](
                              auto, const hci::EventPacket& event) mutable {
    if (hci_is_error(event, WARN, "gap-bredr", "read scan enable failed")) {
      finish_cb(event.ToStatus());
      return;
    }

    auto params = event.return_params<hci::ReadScanEnableReturnParams>();
    uint8_t scan_type = params->scan_enable;
    if (enabled) {
      scan_type |= static_cast<uint8_t>(hci::ScanEnableBit::kPage);
    } else {
      scan_type &= ~static_cast<uint8_t>(hci::ScanEnableBit::kPage);
    }
    auto write_enable = hci::CommandPacket::New(
        hci::kWriteScanEnable, sizeof(hci::WriteScanEnableCommandParams));
    write_enable->mutable_view()
        ->mutable_payload<hci::WriteScanEnableCommandParams>()
        ->scan_enable = scan_type;
    hci->command_channel()->SendCommand(
        std::move(write_enable), dispatcher,
        [cb = std::move(finish_cb), enabled](
            auto, const hci::EventPacket& event) { cb(event.ToStatus()); });
  };
  hci->command_channel()->SendCommand(std::move(read_enable), dispatcher,
                                      std::move(finish_enable_cb));
}

}  // namespace

hci::CommandChannel::EventHandlerId BrEdrConnectionManager::AddEventHandler(
    const hci::EventCode& code, hci::CommandChannel::EventCallback cb) {
  auto self = weak_ptr_factory_.GetWeakPtr();
  auto event_id = hci_->command_channel()->AddEventHandler(
      code,
      [self, callback = std::move(cb)](const auto& event) {
        if (self) {
          callback(event);
        }
      },
      dispatcher_);
  ZX_DEBUG_ASSERT(event_id);
  return event_id;
}

BrEdrConnectionManager::BrEdrConnectionManager(
    fxl::RefPtr<hci::Transport> hci, RemoteDeviceCache* device_cache,
    fbl::RefPtr<data::Domain> data_domain, bool use_interlaced_scan)
    : hci_(hci),
      cache_(device_cache),
      data_domain_(data_domain),
      interrogator_(cache_, hci_, async_get_default_dispatcher()),
      page_scan_interval_(0),
      page_scan_window_(0),
      use_interlaced_scan_(use_interlaced_scan),
      dispatcher_(async_get_default_dispatcher()),
      weak_ptr_factory_(this) {
  ZX_DEBUG_ASSERT(hci_);
  ZX_DEBUG_ASSERT(cache_);
  ZX_DEBUG_ASSERT(data_domain_);
  ZX_DEBUG_ASSERT(dispatcher_);

  hci_cmd_runner_ =
      std::make_unique<hci::SequentialCommandRunner>(dispatcher_, hci_);

  // Register event handlers
  conn_complete_handler_id_ = AddEventHandler(
      hci::kConnectionCompleteEventCode,
      fbl::BindMember(this, &BrEdrConnectionManager::OnConnectionComplete));
  conn_request_handler_id_ = AddEventHandler(
      hci::kConnectionRequestEventCode,
      fbl::BindMember(this, &BrEdrConnectionManager::OnConnectionRequest));
  disconn_cmpl_handler_id_ = AddEventHandler(
      hci::kDisconnectionCompleteEventCode,
      fbl::BindMember(this, &BrEdrConnectionManager::OnDisconnectionComplete));
  io_cap_req_handler_id_ = AddEventHandler(
      hci::kIOCapabilityRequestEventCode,
      fbl::BindMember(this, &BrEdrConnectionManager::OnIOCapabilitiesRequest));
  user_conf_handler_id_ = AddEventHandler(
      hci::kUserConfirmationRequestEventCode,
      fbl::BindMember(this,
                      &BrEdrConnectionManager::OnUserConfirmationRequest));
};

BrEdrConnectionManager::~BrEdrConnectionManager() {
  // Disconnect any connections that we're holding.
  connections_.clear();
  SetPageScanEnabled(false, hci_, dispatcher_, [](const auto) {});
  hci_->command_channel()->RemoveEventHandler(conn_request_handler_id_);
  hci_->command_channel()->RemoveEventHandler(conn_complete_handler_id_);
  hci_->command_channel()->RemoveEventHandler(disconn_cmpl_handler_id_);
  hci_->command_channel()->RemoveEventHandler(io_cap_req_handler_id_);
  hci_->command_channel()->RemoveEventHandler(user_conf_handler_id_);
}

void BrEdrConnectionManager::SetConnectable(bool connectable,
                                            hci::StatusCallback status_cb) {
  auto self = weak_ptr_factory_.GetWeakPtr();
  if (!connectable) {
    SetPageScanEnabled(false, hci_, dispatcher_,
                       [self, cb = std::move(status_cb)](const auto& status) {
                         if (self) {
                           self->page_scan_interval_ = 0;
                           self->page_scan_window_ = 0;
                         } else if (status) {
                           cb(hci::Status(common::HostError::kFailed));
                           return;
                         }
                         cb(status);
                       });
    return;
  }

  WritePageScanSettings(
      hci::kPageScanR1Interval, hci::kPageScanR1Window, use_interlaced_scan_,
      [self, cb = std::move(status_cb)](const auto& status) mutable {
        if (bt_is_error(status, WARN, "gap-bredr",
                        "Write Page Scan Settings failed")) {
          cb(status);
          return;
        }
        if (!self) {
          cb(hci::Status(common::HostError::kFailed));
          return;
        }
        SetPageScanEnabled(true, self->hci_, self->dispatcher_, std::move(cb));
      });
}

void BrEdrConnectionManager::SetPairingDelegate(
    fxl::WeakPtr<PairingDelegate> delegate) {
  // TODO(armansito): implement
}

std::string BrEdrConnectionManager::GetPeerId(
    hci::ConnectionHandle handle) const {
  auto it = connections_.find(handle);
  if (it == connections_.end()) {
    return "";
  }

  auto* device = cache_->FindDeviceByAddress(it->second->peer_address());
  ZX_DEBUG_ASSERT_MSG(device, "Couldn't find device for handle %#.4x", handle);
  return device->identifier();
}

void BrEdrConnectionManager::WritePageScanSettings(uint16_t interval,
                                                   uint16_t window,
                                                   bool interlaced,
                                                   hci::StatusCallback cb) {
  auto self = weak_ptr_factory_.GetWeakPtr();
  if (!hci_cmd_runner_->IsReady()) {
    // TODO(jamuraa): could run the three "settings" commands in parallel and
    // remove the sequence runner.
    cb(hci::Status(common::HostError::kInProgress));
    return;
  }

  auto write_activity =
      hci::CommandPacket::New(hci::kWritePageScanActivity,
                              sizeof(hci::WritePageScanActivityCommandParams));
  auto* activity_params =
      write_activity->mutable_view()
          ->mutable_payload<hci::WritePageScanActivityCommandParams>();
  activity_params->page_scan_interval = htole16(interval);
  activity_params->page_scan_window = htole16(window);

  hci_cmd_runner_->QueueCommand(
      std::move(write_activity),
      [self, interval, window](const hci::EventPacket& event) {
        if (!self || hci_is_error(event, WARN, "gap-bredr",
                                  "write page scan activity failed")) {
          return;
        }

        self->page_scan_interval_ = interval;
        self->page_scan_window_ = window;

        bt_log(SPEW, "gap-bredr", "page scan activity updated");
      });

  auto write_type = hci::CommandPacket::New(
      hci::kWritePageScanType, sizeof(hci::WritePageScanTypeCommandParams));
  auto* type_params =
      write_type->mutable_view()
          ->mutable_payload<hci::WritePageScanTypeCommandParams>();
  type_params->page_scan_type = (interlaced ? hci::PageScanType::kInterlacedScan
                                            : hci::PageScanType::kStandardScan);

  hci_cmd_runner_->QueueCommand(
      std::move(write_type), [self, interlaced](const hci::EventPacket& event) {
        if (!self || hci_is_error(event, WARN, "gap-bredr",
                                  "write page scan type failed")) {
          return;
        }

        self->page_scan_type_ = (interlaced ? hci::PageScanType::kInterlacedScan
                                            : hci::PageScanType::kStandardScan);

        bt_log(SPEW, "gap-bredr", "page scan type updated");
      });

  hci_cmd_runner_->RunCommands(std::move(cb));
}

void BrEdrConnectionManager::OnConnectionRequest(
    const hci::EventPacket& event) {
  ZX_DEBUG_ASSERT(event.event_code() == hci::kConnectionRequestEventCode);
  const auto& params =
      event.view().payload<hci::ConnectionRequestEventParams>();
  std::string link_type_str =
      params.link_type == hci::LinkType::kACL ? "ACL" : "(e)SCO";

  bt_log(TRACE, "gap-bredr", "%s conn request from %s (%s)",
         link_type_str.c_str(), params.bd_addr.ToString().c_str(),
         params.class_of_device.ToString().c_str());

  if (params.link_type == hci::LinkType::kACL) {
    // Accept the connection, performing a role switch. We receive a
    // Connection Complete event when the connection is complete, and finish
    // the link then.
    bt_log(INFO, "gap-bredr", "accept incoming connection");

    auto accept = hci::CommandPacket::New(
        hci::kAcceptConnectionRequest,
        sizeof(hci::AcceptConnectionRequestCommandParams));
    auto accept_params =
        accept->mutable_view()
            ->mutable_payload<hci::AcceptConnectionRequestCommandParams>();
    accept_params->bd_addr = params.bd_addr;
    accept_params->role = hci::ConnectionRole::kMaster;

    hci_->command_channel()->SendCommand(std::move(accept), dispatcher_,
                                         nullptr, hci::kCommandStatusEventCode);
    return;
  }

  // Reject this connection.
  bt_log(INFO, "gap-bredr", "reject unsupported connection");

  auto reject = hci::CommandPacket::New(
      hci::kRejectConnectionRequest,
      sizeof(hci::RejectConnectionRequestCommandParams));
  auto reject_params =
      reject->mutable_view()
          ->mutable_payload<hci::RejectConnectionRequestCommandParams>();
  reject_params->bd_addr = params.bd_addr;
  reject_params->reason = hci::StatusCode::kConnectionRejectedBadBdAddr;

  hci_->command_channel()->SendCommand(std::move(reject), dispatcher_, nullptr,
                                       hci::kCommandStatusEventCode);
}

void BrEdrConnectionManager::OnConnectionComplete(
    const hci::EventPacket& event) {
  ZX_DEBUG_ASSERT(event.event_code() == hci::kConnectionCompleteEventCode);
  const auto& params =
      event.view().payload<hci::ConnectionCompleteEventParams>();
  bt_log(TRACE, "gap-bredr",
         "%s connection complete (status %#.2x, handle: %#.4x)",
         params.bd_addr.ToString().c_str(), params.status,
         params.connection_handle);
  if (hci_is_error(event, WARN, "gap-bredr", "connection error")) {
    return;
  }
  common::DeviceAddress addr(common::DeviceAddress::Type::kBREDR,
                             params.bd_addr);

  // TODO(jamuraa): support non-master connections.
  auto conn_ptr = hci::Connection::CreateACL(
      params.connection_handle, hci::Connection::Role::kMaster,
      common::DeviceAddress(),  // TODO(armansito): Pass local BD_ADDR here.
      addr, hci_);

  if (params.link_type != hci::LinkType::kACL) {
    // Drop the connection if we don't support it.
    return;
  }

  RemoteDevice* device = cache_->FindDeviceByAddress(addr);
  if (!device) {
    device = cache_->NewDevice(addr, true);
  }

  device->MutBrEdr().SetConnectionState(
      RemoteDevice::ConnectionState::kInitializing);

  // Interrogate this device to find out its version/capabilities.
  interrogator_.Start(
      device->identifier(), std::move(conn_ptr),
      [device, self = weak_ptr_factory_.GetWeakPtr()](auto status,
                                                      auto conn_ptr) {
        if (bt_is_error(status, WARN, "gap-bredr",
                        "interrogate failed, dropping connection")) {
          return;
        }

        bt_log(SPEW, "gap-bredr", "interrogation complete for %#.4x",
               conn_ptr->handle());

        if (!self) {
          return;
        }

        // TODO(armansito): Implement this callback.
        auto security_callback = [](hci::ConnectionHandle handle,
                                    sm::SecurityLevel level, auto cb) {
          bt_log(INFO, "gap-bredr",
                 "Ignoring security upgrade request; not implemented");
          cb(sm::Status(HostError::kNotSupported));
        };

        // Register with L2CAP to handle services on the ACL signaling channel.
        self->data_domain_->AddACLConnection(
            conn_ptr->handle(), conn_ptr->role(),
            [self, conn_ptr = conn_ptr->WeakPtr()] {
              if (!self || !conn_ptr) {
                return;
              }

              bt_log(ERROR, "gap-bredr",
                     "Link error received, closing connection %#.4x",
                     conn_ptr->handle());

              // Clean up after receiving the DisconnectComplete event.
              // TODO(NET-1442): Test link error behavior using FakeDevice.
              conn_ptr->Close();
            },
            std::move(security_callback), self->dispatcher_);

        self->connections_.emplace(conn_ptr->handle(), std::move(conn_ptr));
        device->MutBrEdr().SetConnectionState(
            RemoteDevice::ConnectionState::kConnected);
        // TODO(NET-1019): Start SDP service discovery.
      });
}

void BrEdrConnectionManager::OnDisconnectionComplete(
    const hci::EventPacket& event) {
  ZX_DEBUG_ASSERT(event.event_code() == hci::kDisconnectionCompleteEventCode);
  const auto& params =
      event.view().payload<hci::DisconnectionCompleteEventParams>();

  hci::ConnectionHandle handle = le16toh(params.connection_handle);
  if (hci_is_error(event, WARN, "gap-bredr",
                   "HCI disconnection error handle %#.4x", handle)) {
    return;
  }

  auto it = connections_.find(handle);

  if (it == connections_.end()) {
    bt_log(TRACE, "gap-bredr", "disconnect from unknown handle %#.4x", handle);
    return;
  }

  auto* device = cache_->FindDeviceByAddress(it->second->peer_address());
  ZX_DEBUG_ASSERT_MSG(device, "Couldn't find RemoteDevice for handle: %#.4x",
                      handle);
  device->MutBrEdr().SetConnectionState(
      RemoteDevice::ConnectionState::kNotConnected);
  auto conn = std::move(it->second);
  connections_.erase(it);

  bt_log(INFO, "gap-bredr",
         "%s disconnected - %s, handle: %#.4x, reason: %#.2x",
         device->identifier().c_str(), event.ToStatus().ToString().c_str(),
         handle, params.reason);

  data_domain_->RemoveConnection(handle);

  // Connection is already closed, so we don't need to send a disconnect.
  conn->set_closed();
}

void BrEdrConnectionManager::OnIOCapabilitiesRequest(
    const hci::EventPacket& event) {
  ZX_DEBUG_ASSERT(event.event_code() == hci::kIOCapabilityRequestEventCode);
  const auto& params =
      event.view().payload<hci::IOCapabilityRequestEventParams>();

  auto reply = hci::CommandPacket::New(
      hci::kIOCapabilityRequestReply,
      sizeof(hci::IOCapabilityRequestReplyCommandParams));
  auto reply_params =
      reply->mutable_view()
          ->mutable_payload<hci::IOCapabilityRequestReplyCommandParams>();

  reply_params->bd_addr = params.bd_addr;
  // TODO(jamuraa, NET-882): ask the PairingDelegate if it's set what the IO
  // capabilities it has.
  reply_params->io_capability = hci::IOCapability::kNoInputNoOutput;
  // TODO(NET-1155): Add OOB status from RemoteDeviceCache.
  reply_params->oob_data_present = 0x00;  // None present.
  // TODO(jamuraa): Determine this based on the service requirements.
  reply_params->auth_requirements = hci::AuthRequirements::kNoBonding;

  hci_->command_channel()->SendCommand(std::move(reply), dispatcher_, nullptr);
}

void BrEdrConnectionManager::OnUserConfirmationRequest(
    const hci::EventPacket& event) {
  ZX_DEBUG_ASSERT(event.event_code() == hci::kUserConfirmationRequestEventCode);
  const auto& params =
      event.view().payload<hci::UserConfirmationRequestEventParams>();

  bt_log(INFO, "gap-bredr", "auto-confirming pairing from %s (%lu)",
         params.bd_addr.ToString().c_str(), params.numeric_value);

  // TODO(jamuraa, NET-882): if we are not NoInput/NoOutput then we need to ask
  // the pairing delegate.  This currently will auto accept any pairing
  // (JustWorks)
  auto reply = hci::CommandPacket::New(
      hci::kUserConfirmationRequestReply,
      sizeof(hci::UserConfirmationRequestReplyCommandParams));
  auto reply_params =
      reply->mutable_view()
          ->mutable_payload<hci::UserConfirmationRequestReplyCommandParams>();

  reply_params->bd_addr = params.bd_addr;

  hci_->command_channel()->SendCommand(std::move(reply), dispatcher_, nullptr);
}

}  // namespace gap
}  // namespace btlib
