// Copyright 2020 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 "src/connectivity/bluetooth/core/bt-host/gap/low_energy_interrogator.h"

#include "src/connectivity/bluetooth/core/bt-host/gap/peer.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/transport.h"

namespace bt::gap {

LowEnergyInterrogator::LowEnergyInterrogator(PeerCache* cache, fxl::RefPtr<hci::Transport> hci,
                                             async_dispatcher_t* dispatcher)
    : Interrogator(cache, std::move(hci), dispatcher), weak_ptr_factory_(this) {}

void LowEnergyInterrogator::SendCommands(InterrogationRefPtr interrogation) {
  Peer* peer = peer_cache()->FindById(interrogation->peer_id());
  if (!peer) {
    interrogation->Complete(hci::Status(HostError::kFailed));
    return;
  }

  ZX_ASSERT(peer->le().has_value());

  if (!peer->version().has_value()) {
    ReadRemoteVersionInformation(interrogation);
  }

  if (!peer->le()->features().has_value()) {
    ReadLERemoteFeatures(interrogation);
  }
}

void LowEnergyInterrogator::ReadLERemoteFeatures(InterrogationRefPtr interrogation) {
  auto packet = hci::CommandPacket::New(hci::kLEReadRemoteFeatures,
                                        sizeof(hci::LEReadRemoteFeaturesCommandParams));
  auto params = packet->mutable_payload<hci::LEReadRemoteFeaturesCommandParams>();
  params->connection_handle = htole16(interrogation->handle());

  auto cmd_cb = [interrogation, self = weak_ptr_factory_.GetWeakPtr()](
                    auto id, const hci::EventPacket& event) {
    if (!interrogation->active()) {
      return;
    }

    if (hci_is_error(event, WARN, "gap-le", "LE read remote features failed")) {
      interrogation->Complete(event.ToStatus());
      return;
    }

    if (event.event_code() == hci::kCommandStatusEventCode) {
      return;
    }

    ZX_ASSERT(event.event_code() == hci::kLEMetaEventCode);

    bt_log(SPEW, "gap-le", "LE read remote features complete (peer id: %s)",
           bt_str(interrogation->peer_id()));

    const auto* params = event.le_event_params<hci::LEReadRemoteFeaturesCompleteSubeventParams>();

    Peer* peer = self->peer_cache()->FindById(interrogation->peer_id());
    if (!peer) {
      interrogation->Complete(hci::Status(HostError::kFailed));
      return;
    }

    peer->MutLe().SetFeatures(hci::LESupportedFeatures{params->le_features});
  };

  bt_log(SPEW, "gap-le", "sending LE read remote features command (peer id: %s)",
         bt_str(interrogation->peer_id()));
  hci()->command_channel()->SendLeAsyncCommand(std::move(packet), dispatcher(), std::move(cmd_cb),
                                               hci::kLEReadRemoteFeaturesCompleteSubeventCode);
}

}  // namespace bt::gap
