// Copyright 2017 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 "commands.h"

#include <endian.h>
#include <lib/zx/time.h>

#include <cstring>
#include <iostream>

#include "src/connectivity/bluetooth/core/bt-host/common/advertising_data.h"
#include "src/connectivity/bluetooth/core/bt-host/common/manufacturer_names.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/gap.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/advertising_report_parser.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/control_packets.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/util.h"
#include "src/lib/fxl/strings/join_strings.h"
#include "src/lib/fxl/strings/string_number_conversions.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace hcitool {
namespace {

::bt::hci::CommandChannel::TransactionId SendCommand(
    const CommandData* cmd_data, std::unique_ptr<::bt::hci::CommandPacket> packet,
    ::bt::hci::CommandChannel::CommandCallback cb, fit::closure complete_cb) {
  return cmd_data->cmd_channel()->SendCommand(
      std::move(packet),
      [complete_cb = std::move(complete_cb), cb = std::move(cb)](
          ::bt::hci::CommandChannel::TransactionId id, const ::bt::hci::EventPacket& event) {
        if (event.event_code() == ::bt::hci::kCommandStatusEventCode) {
          auto status = event.ToStatus();
          std::cout << "  Command Status: " << status.ToString() << " (id=" << id << ")"
                    << std::endl;
          if (status) {
            complete_cb();
          }
          return;
        }
        cb(id, event);
      });
}

void LogCommandResult(::bt::hci::StatusCode status, ::bt::hci::CommandChannel::TransactionId id,
                      const std::string& event_name = "Command Complete") {
  std::cout << fxl::StringPrintf("  %s - status: 0x%02x (id=%lu)\n", event_name.c_str(), status,
                                 id);
}

::bt::hci::CommandChannel::TransactionId SendCompleteCommand(
    const CommandData* cmd_data, std::unique_ptr<::bt::hci::CommandPacket> packet,
    fit::closure complete_cb) {
  auto cb = [complete_cb = complete_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                const ::bt::hci::EventPacket& event) {
    auto return_params = event.return_params<::bt::hci::SimpleReturnParams>();
    LogCommandResult(return_params->status, id);
    complete_cb();
  };
  return SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));
}

// TODO(armansito): Move this to a library header as it will be useful
// elsewhere.
std::string AdvEventTypeToString(::bt::hci::LEAdvertisingEventType type) {
  switch (type) {
    case ::bt::hci::LEAdvertisingEventType::kAdvInd:
      return "ADV_IND";
    case ::bt::hci::LEAdvertisingEventType::kAdvDirectInd:
      return "ADV_DIRECT_IND";
    case ::bt::hci::LEAdvertisingEventType::kAdvScanInd:
      return "ADV_SCAN_IND";
    case ::bt::hci::LEAdvertisingEventType::kAdvNonConnInd:
      return "ADV_NONCONN_IND";
    case ::bt::hci::LEAdvertisingEventType::kScanRsp:
      return "SCAN_RSP";
    default:
      break;
  }
  return "(unknown)";
}

// TODO(armansito): Move this to a library header as it will be useful
// elsewhere.
std::string BdAddrTypeToString(::bt::hci::LEAddressType type) {
  switch (type) {
    case ::bt::hci::LEAddressType::kPublic:
      return "public";
    case ::bt::hci::LEAddressType::kRandom:
      return "random";
    case ::bt::hci::LEAddressType::kPublicIdentity:
      return "public-identity (resolved private)";
    case ::bt::hci::LEAddressType::kRandomIdentity:
      return "random-identity (resolved private)";
    default:
      break;
  }
  return "(unknown)";
}

// TODO(armansito): Move this to a library header as it will be useful
// elsewhere.
std::vector<std::string> AdvFlagsToStrings(uint8_t flags) {
  std::vector<std::string> flags_list;
  if (flags & ::bt::AdvFlag::kLELimitedDiscoverableMode)
    flags_list.push_back("limited-discoverable");
  if (flags & ::bt::AdvFlag::kLEGeneralDiscoverableMode)
    flags_list.push_back("general-discoverable");
  if (flags & ::bt::AdvFlag::kBREDRNotSupported)
    flags_list.push_back("bredr-not-supported");
  if (flags & ::bt::AdvFlag::kSimultaneousLEAndBREDRController)
    flags_list.push_back("le-and-bredr-controller");
  if (flags & ::bt::AdvFlag::kSimultaneousLEAndBREDRHost)
    flags_list.push_back("le-and-bredr-host");
  return flags_list;
}

void DisplayAdvertisingReport(const ::bt::hci::LEAdvertisingReportData& data, int8_t rssi,
                              const std::string& name_filter, const std::string& addr_type_filter) {
  ::bt::SupplementDataReader reader(::bt::BufferView(data.data, data.length_data));

  // The AD fields that we'll parse out.
  uint8_t flags = 0;
  std::string_view short_name, complete_name;
  int8_t tx_power_lvl;
  bool tx_power_present = false;

  ::bt::DataType type;
  ::bt::BufferView adv_data_field;
  while (reader.GetNextField(&type, &adv_data_field)) {
    switch (type) {
      case ::bt::DataType::kFlags:
        flags = adv_data_field.data()[0];
        break;
      case ::bt::DataType::kCompleteLocalName:
        complete_name = adv_data_field.AsString();
        break;
      case ::bt::DataType::kShortenedLocalName:
        short_name = adv_data_field.AsString();
        break;
      case ::bt::DataType::kTxPowerLevel:
        tx_power_present = true;
        tx_power_lvl = adv_data_field.data()[0];
        break;
      default:
        break;
    }
  }

  // First check if this report should be filtered out by name.
  if (!name_filter.empty() && complete_name.compare(name_filter) != 0 &&
      short_name.compare(name_filter) != 0) {
    return;
  }

  // Apply the address type filter.
  if (!addr_type_filter.empty()) {
    FX_DCHECK(addr_type_filter == "public" || addr_type_filter == "random");
    if (addr_type_filter == "public" && data.address_type != ::bt::hci::LEAddressType::kPublic &&
        data.address_type != ::bt::hci::LEAddressType::kPublicIdentity)
      return;
    if (addr_type_filter == "random" && data.address_type != ::bt::hci::LEAddressType::kRandom &&
        data.address_type != ::bt::hci::LEAddressType::kRandomIdentity)
      return;
  }

  std::cout << "  LE Advertising Report:" << std::endl;
  std::cout << "    RSSI: " << fxl::NumberToString(rssi) << std::endl;
  std::cout << "    type: " << AdvEventTypeToString(data.event_type) << std::endl;
  std::cout << "    address type: " << BdAddrTypeToString(data.address_type) << std::endl;
  std::cout << "    BD_ADDR: " << data.address.ToString() << std::endl;
  std::cout << "    Data Length: " << fxl::NumberToString(data.length_data) << " bytes"
            << std::endl;
  if (flags) {
    std::cout << "    Flags: [" << fxl::JoinStrings(AdvFlagsToStrings(flags), ", ") << "]"
              << std::endl;
  }
  if (!short_name.empty())
    std::cout << "    Shortened Local Name: " << short_name << std::endl;
  if (!complete_name.empty())
    std::cout << "    Complete Local Name: " << complete_name << std::endl;
  if (tx_power_present) {
    std::cout << "    Tx Power Level: " << fxl::NumberToString(tx_power_lvl) << std::endl;
  }
}

void DisplayInquiryResult(const ::bt::hci::InquiryResult& result) {
  std::cout << "  Result: " << result.bd_addr.ToString() << " ("
            << result.class_of_device.ToString() << ")" << std::endl;
}

bool HandleVersionInfo(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                       fit::closure complete_cb) {
  if (cmd_line.positional_args().size() || cmd_line.options().size()) {
    std::cout << "  Usage: version-info" << std::endl;
    return false;
  }

  auto cb = [complete_cb = complete_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                const ::bt::hci::EventPacket& event) {
    auto params = event.return_params<::bt::hci::ReadLocalVersionInfoReturnParams>();
    LogCommandResult(params->status, id);
    if (params->status != ::bt::hci::StatusCode::kSuccess) {
      complete_cb();
      return;
    }

    std::cout << "  Version Info:" << std::endl;
    std::cout << "    HCI Version: Core Spec " << ::bt::hci::HCIVersionToString(params->hci_version)
              << std::endl;
    std::cout << "    Manufacturer Name: "
              << ::bt::GetManufacturerName(le16toh(params->manufacturer_name)) << std::endl;

    complete_cb();
  };

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kReadLocalVersionInfo);
  auto id = SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));

  std::cout << "  Sent HCI_Read_Local_Version_Information (id=" << id << ")" << std::endl;
  return true;
}

bool HandleReset(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                 fit::closure complete_cb) {
  if (cmd_line.positional_args().size() || cmd_line.options().size()) {
    std::cout << "  Usage: reset" << std::endl;
    return false;
  }

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kReset);
  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_Reset (id=" << id << ")" << std::endl;

  return true;
}

bool HandleReadBDADDR(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                      fit::closure complete_cb) {
  if (cmd_line.positional_args().size() || cmd_line.options().size()) {
    std::cout << "  Usage: read-bdaddr" << std::endl;
    return false;
  }

  auto cb = [complete_cb = complete_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                const ::bt::hci::EventPacket& event) {
    auto return_params = event.return_params<::bt::hci::ReadBDADDRReturnParams>();
    LogCommandResult(return_params->status, id);
    if (return_params->status != ::bt::hci::StatusCode::kSuccess) {
      complete_cb();
      return;
    }

    std::cout << "  BD_ADDR: " << return_params->bd_addr.ToString() << std::endl;
    complete_cb();
  };

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kReadBDADDR);
  auto id = SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));

  std::cout << "  Sent HCI_Read_BDADDR (id=" << id << ")" << std::endl;

  return true;
}

bool HandleReadLocalName(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                         fit::closure complete_cb) {
  if (cmd_line.positional_args().size() || cmd_line.options().size()) {
    std::cout << "  Usage: read-local-name" << std::endl;
    return false;
  }

  auto cb = [complete_cb = complete_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                const ::bt::hci::EventPacket& event) {
    auto return_params = event.return_params<::bt::hci::ReadLocalNameReturnParams>();
    LogCommandResult(return_params->status, id);
    if (return_params->status != ::bt::hci::StatusCode::kSuccess) {
      complete_cb();
      return;
    }

    std::cout << "  Local Name: " << return_params->local_name << std::endl;

    complete_cb();
  };

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kReadLocalName);
  auto id = SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));
  std::cout << "  Sent HCI_Read_Local_Name (id=" << id << ")" << std::endl;

  return true;
}

bool HandleWriteLocalName(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                          fit::closure complete_cb) {
  if (cmd_line.positional_args().size() != 1 || cmd_line.options().size()) {
    std::cout << "  Usage: write-local-name <name>" << std::endl;
    return false;
  }

  const std::string& name = cmd_line.positional_args()[0];
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kWriteLocalName, name.length() + 1);
  std::strcpy((char*)packet->mutable_payload<::bt::hci::WriteLocalNameCommandParams>()->local_name,
              name.c_str());

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));
  std::cout << "  Sent HCI_Write_Local_Name (id=" << id << ")" << std::endl;

  return true;
}

bool HandleSetEventMask(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                        fit::closure complete_cb) {
  if (cmd_line.positional_args().size() != 1 || cmd_line.options().size()) {
    std::cout << "  Usage: set-event-mask [hex]" << std::endl;
    return false;
  }

  std::string hex = cmd_line.positional_args()[0];
  if (hex.size() >= 2 && hex[0] == '0' && hex[1] == 'x')
    hex = hex.substr(2);

  uint64_t mask;
  if (!fxl::StringToNumberWithError<uint64_t>(hex, &mask, fxl::Base::k16)) {
    std::cout << "  Unrecognized hex number: " << cmd_line.positional_args()[0] << std::endl;
    std::cout << "  Usage: set-event-mask [hex]" << std::endl;
    return false;
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::SetEventMaskCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kSetEventMask, kPayloadSize);
  packet->mutable_payload<::bt::hci::SetEventMaskCommandParams>()->event_mask = htole64(mask);

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_Set_Event_Mask(" << fxl::NumberToString(mask, fxl::Base::k16)
            << ") (id=" << id << ")" << std::endl;
  return true;
}

bool HandleLESetAdvEnable(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                          fit::closure complete_cb) {
  if (cmd_line.positional_args().size() != 1 || cmd_line.options().size()) {
    std::cout << "  Usage: set-adv-enable [enable|disable]" << std::endl;
    return false;
  }

  ::bt::hci::GenericEnableParam value;
  std::string cmd_arg = cmd_line.positional_args()[0];
  if (cmd_arg == "enable") {
    value = ::bt::hci::GenericEnableParam::kEnable;
  } else if (cmd_arg == "disable") {
    value = ::bt::hci::GenericEnableParam::kDisable;
  } else {
    std::cout << "  Unrecognized parameter: " << cmd_arg << std::endl;
    std::cout << "  Usage: set-adv-enable [enable|disable]" << std::endl;
    return false;
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::LESetAdvertisingEnableCommandParams);

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kLESetAdvertisingEnable, kPayloadSize);
  packet->mutable_payload<::bt::hci::LESetAdvertisingEnableCommandParams>()->advertising_enable =
      value;

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_LE_Set_Advertising_Enable (id=" << id << ")" << std::endl;
  return true;
}

bool HandleLESetAdvParams(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                          fit::closure complete_cb) {
  if (cmd_line.positional_args().size()) {
    std::cout << "  Usage: set-adv-params [--help|--type]" << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Options: \n"
                 "    --help - Display this help message\n"
                 "    --type=<type> - The advertising type. Possible values are:\n"
                 "          - nonconn: non-connectable undirected (default)\n"
                 "          - adv-ind: connectable and scannable undirected\n"
                 "          - direct-low: connectable directed low-duty\n"
                 "          - direct-high: connectable directed high-duty\n"
                 "          - scan: scannable undirected";
    std::cout << std::endl;
    return false;
  }

  ::bt::hci::LEAdvertisingType adv_type = ::bt::hci::LEAdvertisingType::kAdvNonConnInd;
  std::string type;
  if (cmd_line.GetOptionValue("type", &type)) {
    if (type == "adv-ind") {
      adv_type = ::bt::hci::LEAdvertisingType::kAdvInd;
    } else if (type == "direct-low") {
      adv_type = ::bt::hci::LEAdvertisingType::kAdvDirectIndLowDutyCycle;
    } else if (type == "direct-high") {
      adv_type = ::bt::hci::LEAdvertisingType::kAdvDirectIndHighDutyCycle;
    } else if (type == "scan") {
      adv_type = ::bt::hci::LEAdvertisingType::kAdvScanInd;
    } else if (type == "nonconn") {
      adv_type = ::bt::hci::LEAdvertisingType::kAdvNonConnInd;
    } else {
      std::cout << "  Unrecognized advertising type: " << type << std::endl;
      return false;
    }
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::LESetAdvertisingParametersCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kLESetAdvertisingParameters, kPayloadSize);
  auto params = packet->mutable_payload<::bt::hci::LESetAdvertisingParametersCommandParams>();
  params->adv_interval_min = htole16(::bt::hci::kLEAdvertisingIntervalDefault);
  params->adv_interval_max = htole16(::bt::hci::kLEAdvertisingIntervalDefault);
  params->adv_type = adv_type;
  params->own_address_type = ::bt::hci::LEOwnAddressType::kPublic;
  params->peer_address_type = ::bt::hci::LEPeerAddressType::kPublic;
  params->peer_address.SetToZero();
  params->adv_channel_map = ::bt::hci::kLEAdvertisingChannelAll;
  params->adv_filter_policy = ::bt::hci::LEAdvFilterPolicy::kAllowAll;

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_LE_Set_Advertising_Parameters (id=" << id << ")" << std::endl;

  return true;
}

bool HandleLESetAdvData(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                        fit::closure complete_cb) {
  if (cmd_line.positional_args().size()) {
    std::cout << "  Usage: set-adv-data [--help|--name]" << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Options: \n"
                 "    --help - Display this help message\n"
                 "    --name=<local-name> - Set the \"Complete Local Name\" field";
    std::cout << std::endl;
    return false;
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::LESetAdvertisingDataCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kLESetAdvertisingData, kPayloadSize);
  packet->mutable_view()->mutable_payload_data().SetToZeros();

  std::string name;
  if (cmd_line.GetOptionValue("name", &name)) {
    // Each advertising data structure consists of a 1 octet length field, 1
    // octet type field.
    size_t adv_data_len = 2 + name.length();
    if (adv_data_len > ::bt::hci::kMaxLEAdvertisingDataLength) {
      std::cout << "  Given name is too long" << std::endl;
      return false;
    }

    auto params = packet->mutable_payload<::bt::hci::LESetAdvertisingDataCommandParams>();
    params->adv_data_length = adv_data_len;
    params->adv_data[0] = adv_data_len - 1;
    params->adv_data[1] = 0x09;  // Complete Local Name
    std::strncpy((char*)params->adv_data + 2, name.c_str(), name.length());
  } else {
    packet->mutable_payload<::bt::hci::LESetAdvertisingDataCommandParams>()->adv_data_length = 0;
  }

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_LE_Set_Advertising_Data (id=" << id << ")" << std::endl;

  return true;
}

bool HandleLESetScanParams(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                           fit::closure complete_cb) {
  if (cmd_line.positional_args().size()) {
    std::cout << "  Usage: set-scan-params [--help|--type]" << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Options: \n"
                 "    --help - Display this help message\n"
                 "    --type=<type> - The scan type. Possible values are:\n"
                 "          - passive: passive scanning (default)\n"
                 "          - active: active scanning; sends scan requests";
    std::cout << std::endl;
    return false;
  }

  ::bt::hci::LEScanType scan_type = ::bt::hci::LEScanType::kPassive;
  std::string type;
  if (cmd_line.GetOptionValue("type", &type)) {
    if (type == "passive") {
      scan_type = ::bt::hci::LEScanType::kPassive;
    } else if (type == "active") {
      scan_type = ::bt::hci::LEScanType::kActive;
    } else {
      std::cout << "  Unrecognized scan type: " << type << std::endl;
      return false;
    }
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::LESetScanParametersCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kLESetScanParameters, kPayloadSize);

  auto params = packet->mutable_payload<::bt::hci::LESetScanParametersCommandParams>();
  params->scan_type = scan_type;
  params->scan_interval = htole16(::bt::hci::kLEScanIntervalDefault);
  params->scan_window = htole16(::bt::hci::kLEScanIntervalDefault);
  params->own_address_type = ::bt::hci::LEOwnAddressType::kPublic;
  params->filter_policy = ::bt::hci::LEScanFilterPolicy::kNoWhiteList;

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_LE_Set_Scan_Parameters (id=" << id << ")" << std::endl;

  return true;
}

bool HandleLEScan(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                  fit::closure complete_cb) {
  if (cmd_line.positional_args().size()) {
    std::cout << "  Usage: set-scan-params "
                 "[--help|--timeout=<t>|--no-dedup|--name-filter]"
              << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Options: \n"
                 "    --help - Display this help message\n"
                 "    --timeout=<t> - Duration (in seconds) during which to scan\n"
                 "                    (default is 10 seconds)\n"
                 "    --no-dedup - Tell the controller not to filter duplicate\n"
                 "                 reports\n"
                 "    --name-filter=<prefix> - Filter advertising reports by local\n"
                 "                             name, if present.\n"
                 "    --addr-type-filter=[public|random]";
    std::cout << std::endl;
    return false;
  }

  auto timeout = zx::sec(10);  // Default to 10 seconds.
  std::string timeout_str;
  if (cmd_line.GetOptionValue("timeout", &timeout_str)) {
    uint32_t time_seconds;
    if (!fxl::StringToNumberWithError(timeout_str, &time_seconds)) {
      std::cout << "  Malformed timeout value: " << timeout_str << std::endl;
      return false;
    }

    timeout = zx::sec(time_seconds);
  }

  std::string name_filter;
  cmd_line.GetOptionValue("name-filter", &name_filter);

  std::string addr_type_filter;
  cmd_line.GetOptionValue("addr-type-filter", &addr_type_filter);
  if (!addr_type_filter.empty() && addr_type_filter != "public" && addr_type_filter != "random") {
    std::cout << "  Unknown address type filter: " << addr_type_filter << std::endl;
    return false;
  }

  ::bt::hci::GenericEnableParam filter_duplicates = ::bt::hci::GenericEnableParam::kEnable;
  if (cmd_line.HasOption("no-dedup")) {
    filter_duplicates = ::bt::hci::GenericEnableParam::kDisable;
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::LESetScanEnableCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kLESetScanEnable, kPayloadSize);

  auto params = packet->mutable_payload<::bt::hci::LESetScanEnableCommandParams>();
  params->scanning_enabled = ::bt::hci::GenericEnableParam::kEnable;
  params->filter_duplicates = filter_duplicates;

  // Event handler to log when we receive advertising reports
  auto le_adv_report_cb = [name_filter, addr_type_filter](const ::bt::hci::EventPacket& event) {
    FX_DCHECK(event.event_code() == ::bt::hci::kLEMetaEventCode);
    FX_DCHECK(event.params<::bt::hci::LEMetaEventParams>().subevent_code ==
              ::bt::hci::kLEAdvertisingReportSubeventCode);

    ::bt::hci::AdvertisingReportParser parser(event);
    const ::bt::hci::LEAdvertisingReportData* data;
    int8_t rssi;
    while (parser.GetNextReport(&data, &rssi)) {
      DisplayAdvertisingReport(*data, rssi, name_filter, addr_type_filter);
    }
    return ::bt::hci::CommandChannel::EventCallbackResult::kContinue;
  };
  auto event_handler_id = cmd_data->cmd_channel()->AddLEMetaEventHandler(
      ::bt::hci::kLEAdvertisingReportSubeventCode, le_adv_report_cb);

  fit::closure cleanup_cb = [complete_cb = complete_cb.share(), event_handler_id,
                             cmd_channel = cmd_data->cmd_channel()] {
    cmd_channel->RemoveEventHandler(event_handler_id);
    complete_cb();
  };

  // The callback invoked after scanning is stopped.
  auto final_cb = [cleanup_cb = cleanup_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                    const ::bt::hci::EventPacket& event) {
    auto return_params = event.return_params<::bt::hci::SimpleReturnParams>();
    LogCommandResult(return_params->status, id);
    cleanup_cb();
  };

  // Delayed task that stops scanning.
  auto scan_disable_cb = [cleanup_cb = cleanup_cb.share(), final_cb = std::move(final_cb),
                          cmd_data]() mutable {
    auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kLESetScanEnable, kPayloadSize);
    auto params = packet->mutable_payload<::bt::hci::LESetScanEnableCommandParams>();
    params->scanning_enabled = ::bt::hci::GenericEnableParam::kDisable;
    params->filter_duplicates = ::bt::hci::GenericEnableParam::kDisable;

    auto id = SendCommand(cmd_data, std::move(packet), std::move(final_cb), std::move(cleanup_cb));

    std::cout << "  Sent HCI_LE_Set_Scan_Enable (disabled) (id=" << id << ")" << std::endl;
  };

  auto cb = [scan_disable_cb = std::move(scan_disable_cb), cleanup_cb = cleanup_cb.share(), timeout,
             dispatcher = cmd_data->dispatcher()](::bt::hci::CommandChannel::TransactionId id,
                                                  const ::bt::hci::EventPacket& event) mutable {
    auto return_params = event.return_params<::bt::hci::SimpleReturnParams>();
    LogCommandResult(return_params->status, id);
    if (return_params->status != ::bt::hci::StatusCode::kSuccess) {
      cleanup_cb();
      return;
    }
    async::PostDelayedTask(dispatcher, std::move(scan_disable_cb), timeout);
  };

  auto id = SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));

  std::cout << "  Sent HCI_LE_Set_Scan_Enable (enabled) (id=" << id << ")" << std::endl;

  return true;
}

bool HandleBRScan(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                  fit::closure complete_cb) {
  if (cmd_line.positional_args().size()) {
    std::cout << "  Usage: scan "
                 "[--help|--timeout=<t>|--filter=<prefix>|--max-responses=<n>]"
              << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Options: \n"
                 "    --help - Display this help message\n"
                 "    --timeout=<t> - Maximum duration (in seconds) of the scan\n"
                 "                    (default is 30 seconds)\n"
                 "    --filter=<prefix> - Filter devices reported by name or\n"
                 "                        BR_ADDR prefix.\n"
                 "    --max-responses=<n> - End scan after n responses are\n"
                 "                          received.\n";
    std::cout << std::endl;
    return false;
  }

  auto timeout = zx::sec(30);  // Default 30 seconds.
  std::string timeout_str;
  if (cmd_line.GetOptionValue("timeout", &timeout_str)) {
    uint32_t time_seconds;
    if (!fxl::StringToNumberWithError(timeout_str, &time_seconds)) {
      std::cout << "  Malformed timeout value: " << timeout_str << std::endl;
      return false;
    }
    // TODO(jamuraa): support longer than 61 second scans by repeating the
    // Inquiry
    if (time_seconds > 61) {
      std::cout << "  Maximum inquiry length is 61 seconds." << std::endl;
      return false;
    }

    timeout = zx::sec(time_seconds);
  }

  std::string filter;
  cmd_line.GetOptionValue("filter", &filter);

  uint8_t max_responses = 0;
  std::string max_responses_str;
  if (cmd_line.GetOptionValue("max-responses", &max_responses_str)) {
    uint32_t responses;
    if (!fxl::StringToNumberWithError(max_responses_str, &responses)) {
      std::cout << "  Malformed maximum responses value: " << max_responses_str << std::endl;
      return false;
    }
    if (responses > 255) {
      std::cout << "  Maximum responses must be less than 255." << std::endl;
      return false;
    }
    max_responses = uint8_t(responses);
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::InquiryCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kInquiry, kPayloadSize);
  auto params = packet->mutable_payload<::bt::hci::InquiryCommandParams>();

  params->lap = ::bt::hci::kGIAC;
  // Always use the maximum inquiry length, we will time it more accurately.
  params->inquiry_length = ::bt::hci::kInquiryLengthMax;
  params->num_responses = max_responses;

  auto event_handler_ids = std::make_shared<std::vector<bt::hci::CommandChannel::EventHandlerId>>();
  fit::closure cleanup_cb = [complete_cb = std::move(complete_cb), event_handler_ids,
                             cmd_channel = cmd_data->cmd_channel()] {
    for (const auto& handler_id : *event_handler_ids) {
      cmd_channel->RemoveEventHandler(handler_id);
    }
    complete_cb();
  };

  // Event handler to log when we receive advertising reports
  auto inquiry_result_cb = [filter](const ::bt::hci::EventPacket& event) {
    FX_DCHECK(event.event_code() == ::bt::hci::kInquiryResultEventCode);

    const auto& result = event.params<::bt::hci::InquiryResultEventParams>();

    for (int i = 0; i < result.num_responses; i++) {
      if (!filter.empty() &&
          !filter.compare(0, filter.length(), result.responses[i].bd_addr.ToString())) {
        continue;
      }
      DisplayInquiryResult(result.responses[i]);
    }
    return ::bt::hci::CommandChannel::EventCallbackResult::kContinue;
  };

  event_handler_ids->push_back(cmd_data->cmd_channel()->AddEventHandler(
      ::bt::hci::kInquiryResultEventCode, std::move(inquiry_result_cb)));

  // The callback invoked for an Inquiry Complete response.
  auto inquiry_complete_cb = [cleanup_cb =
                                  cleanup_cb.share()](const ::bt::hci::EventPacket& event) mutable {
    auto params = event.params<::bt::hci::InquiryCompleteEventParams>();
    std::cout << fxl::StringPrintf("  Inquiry Complete - status: 0x%02x\n", params.status);
    cleanup_cb();
    return ::bt::hci::CommandChannel::EventCallbackResult::kContinue;
  };

  event_handler_ids->push_back(cmd_data->cmd_channel()->AddEventHandler(
      ::bt::hci::kInquiryCompleteEventCode, std::move(inquiry_complete_cb)));

  // Delayed task that stops scanning.
  auto inquiry_cancel_cb = [cleanup_cb = cleanup_cb.share(), cmd_data]() mutable {
    auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kInquiryCancel, 0);
    auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(cleanup_cb));
    std::cout << "  Sent HCI_Inquiry_Cancel (id=" << id << ")" << std::endl;
  };

  auto cb = [inquiry_cancel_cb = std::move(inquiry_cancel_cb), cleanup_cb = cleanup_cb.share(),
             timeout,
             dispatcher = cmd_data->dispatcher()](::bt::hci::CommandChannel::TransactionId id,
                                                  const ::bt::hci::EventPacket& event) mutable {
    auto return_params = event.params<::bt::hci::CommandStatusEventParams>();
    LogCommandResult(return_params.status, id, "Command Status");
    if (return_params.status != ::bt::hci::StatusCode::kSuccess) {
      cleanup_cb();
      return;
    }
    async::PostDelayedTask(dispatcher, std::move(inquiry_cancel_cb), timeout);
  };

  // Inquiry sends a Command Status, and then we wait for the Inquiry Complete,
  // or the timer to run out, for a long time. Count this as "complete" when the
  // Status comes in.
  auto id = cmd_data->cmd_channel()->SendCommand(std::move(packet), std::move(cb),
                                                 ::bt::hci::kCommandStatusEventCode);
  std::cout << "  Sent HCI_Inquiry (id=" << id << ")" << std::endl;

  return true;
}

bool HandleWritePageScanActivity(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                                 fit::closure complete_cb) {
  if (cmd_line.positional_args().size()) {
    std::cout << "  Usage: write-page-scan-activity [--help\n"
                 "                                   |--interval=<interval>\n"
                 "                                   |--window=<window>]"
              << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Options:\n"
                 "    --help - Display this help message\n"
                 "    --mode=R0|R1|R2 - Use a specific scanning mode\n"
                 "    --interval=<interval> - Set page scan interval (in hex)\n"
                 "    --window=<window> - Set page scan window (in hex)\n";
    std::cout << std::endl;
    return false;
  }

  uint16_t page_scan_interval = ::bt::hci::kPageScanR1Interval;
  uint16_t page_scan_window = ::bt::hci::kPageScanR1Window;

  std::string mode_str;
  if (cmd_line.GetOptionValue("mode", &mode_str)) {
    if (mode_str == "R0") {
      page_scan_interval = ::bt::hci::kPageScanR0Interval;
      page_scan_window = ::bt::hci::kPageScanR0Window;
    } else if (mode_str == "R1") {
      page_scan_interval = ::bt::hci::kPageScanR1Interval;
      page_scan_window = ::bt::hci::kPageScanR1Window;
    } else if (mode_str == "R2") {
      page_scan_interval = ::bt::hci::kPageScanR2Interval;
      page_scan_window = ::bt::hci::kPageScanR2Window;
    } else {
      std::cout << "  Unrecognized mode value: " << mode_str << std::endl;
      return false;
    }
  }

  // Check for manual settings.
  std::string interval_str;
  if (cmd_line.GetOptionValue("interval", &interval_str)) {
    uint16_t parsed_interval;
    if (!fxl::StringToNumberWithError(interval_str, &parsed_interval, fxl::Base::k16)) {
      std::cout << "  Malformed interval value: " << interval_str << std::endl;
      return false;
    }
    if (parsed_interval < ::bt::hci::kPageScanIntervalMin ||
        parsed_interval > ::bt::hci::kPageScanIntervalMax) {
      std::cout << "  Interval value is out of the allowed range." << std::endl;
      return false;
    }
    if (parsed_interval % 2 != 0) {
      std::cout << "  Interval value must be even." << std::endl;
      return false;
    }

    page_scan_interval = parsed_interval;
  }

  std::string window_str;
  if (cmd_line.GetOptionValue("window", &window_str)) {
    uint16_t parsed_window;
    if (!fxl::StringToNumberWithError(window_str, &parsed_window, fxl::Base::k16)) {
      std::cout << "  Malformed window value: " << window_str << std::endl;
      return false;
    }
    if (parsed_window < ::bt::hci::kPageScanWindowMin ||
        parsed_window > ::bt::hci::kPageScanWindowMax) {
      std::cout << "  Window value is out of the allowed range." << std::endl;
      return false;
    }
    if (parsed_window > page_scan_interval) {
      std::cout << "  Window value must be less than or equal to interval value." << std::endl;
      return false;
    }

    page_scan_window = parsed_window;
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::WritePageScanActivityCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kWritePageScanActivity, kPayloadSize);
  auto params = packet->mutable_payload<::bt::hci::WritePageScanActivityCommandParams>();
  params->page_scan_interval = page_scan_interval;
  params->page_scan_window = page_scan_window;

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_Write_Page_Scan_Activity (id=" << id << ")" << std::endl;

  return true;
}

bool HandleReadPageScanActivity(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                                fit::closure complete_cb) {
  if (cmd_line.positional_args().size() || cmd_line.options().size()) {
    std::cout << "  Usage: read-page-scan-activity" << std::endl;
    return false;
  }

  auto cb = [complete_cb = complete_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                const ::bt::hci::EventPacket& event) {
    auto return_params = event.return_params<::bt::hci::ReadPageScanActivityReturnParams>();
    LogCommandResult(return_params->status, id);
    if (return_params->status != ::bt::hci::StatusCode::kSuccess) {
      complete_cb();
      return;
    }

    std::cout << "  Interval: " << return_params->page_scan_interval << std::endl;
    std::cout << "  Window: " << return_params->page_scan_window << std::endl;

    complete_cb();
  };

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kReadPageScanActivity);
  auto id = SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));
  std::cout << "  Sent HCI_Read_Page_Scan_Activity (id=" << id << ")" << std::endl;

  return true;
}

bool HandleWritePageScanType(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                             fit::closure complete_cb) {
  if (cmd_line.positional_args().size()) {
    std::cout << "  Usage: write-page-scan-type [--help|--standard|--interlaced]" << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Options:\n"
                 "    --help - Display this help message\n"
                 "    --type=standard|interlaced - Choose scanning type";
    std::cout << std::endl;
    return false;
  }

  ::bt::hci::PageScanType page_scan_type = ::bt::hci::PageScanType::kStandardScan;
  std::string type_str;
  if (cmd_line.GetOptionValue("type", &type_str)) {
    if (type_str == "standard") {
      page_scan_type = ::bt::hci::PageScanType::kStandardScan;
    } else if (type_str == "interlaced") {
      page_scan_type = ::bt::hci::PageScanType::kInterlacedScan;
    } else {
      std::cout << "  Unrecognized type: " << type_str << std::endl;
    }
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::WritePageScanTypeCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kWritePageScanType, kPayloadSize);

  packet->mutable_payload<::bt::hci::WritePageScanTypeCommandParams>()->page_scan_type =
      page_scan_type;

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_Write_Page_Scan_Type (id=" << id << ")" << std::endl;

  return true;
}

bool HandleReadPageScanType(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                            fit::closure complete_cb) {
  if (cmd_line.positional_args().size() || cmd_line.options().size()) {
    std::cout << "  Usage: read-page-scan-type" << std::endl;
    return false;
  }

  auto cb = [complete_cb = complete_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                const ::bt::hci::EventPacket& event) {
    auto return_params = event.return_params<::bt::hci::ReadPageScanTypeReturnParams>();
    LogCommandResult(return_params->status, id);
    if (return_params->status != ::bt::hci::StatusCode::kSuccess) {
      complete_cb();
      return;
    }

    if (return_params->page_scan_type == ::bt::hci::PageScanType::kStandardScan) {
      std::cout << "  Type: standard" << std::endl;
    } else if (return_params->page_scan_type == ::bt::hci::PageScanType::kInterlacedScan) {
      std::cout << "  Type: interlaced" << std::endl;
    } else {
      std::cout << "  Type: unknown" << std::endl;
    }

    complete_cb();
  };

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kReadPageScanType);
  auto id = SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));
  std::cout << "  Sent HCI_Read_Page_Scan_Type (id=" << id << ")" << std::endl;

  return true;
}

bool HandleWriteScanEnable(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                           fit::closure complete_cb) {
  if (cmd_line.positional_args().size() > 2) {
    std::cout << "  Usage: write-scan-enable [--help] [page] [inquiry]" << std::endl;
    return false;
  }

  if (cmd_line.HasOption("help")) {
    std::cout << "  Arguments:\n"
                 "    include \"page\" to enable page scan\n"
                 "    include \"inquiry\" to enable inquiry scan\n"
                 "  Options:\n"
                 "    --help - Display this help message";
    std::cout << std::endl;
    return false;
  }

  ::bt::hci::ScanEnableType scan_enable = 0x00;
  for (std::string positional_arg : cmd_line.positional_args()) {
    if (positional_arg == "inquiry") {
      scan_enable |= (::bt::hci::ScanEnableType)::bt::hci::ScanEnableBit::kInquiry;
    } else if (positional_arg == "page") {
      scan_enable |= (::bt::hci::ScanEnableType)::bt::hci::ScanEnableBit::kPage;
    } else {
      std::cout << "  Unrecognized positional argument: " << positional_arg << std::endl;
      return false;
    }
  }

  constexpr size_t kPayloadSize = sizeof(::bt::hci::WriteScanEnableCommandParams);
  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kWriteScanEnable, kPayloadSize);

  packet->mutable_payload<::bt::hci::WriteScanEnableCommandParams>()->scan_enable = scan_enable;

  auto id = SendCompleteCommand(cmd_data, std::move(packet), std::move(complete_cb));

  std::cout << "  Sent HCI_Write_Scan_Enable (id=" << id << ")" << std::endl;

  return true;
}

bool HandleReadScanEnable(const CommandData* cmd_data, const fxl::CommandLine& cmd_line,
                          fit::closure complete_cb) {
  if (cmd_line.positional_args().size() || cmd_line.options().size()) {
    std::cout << "  Usage: read-scan-enable" << std::endl;
    return false;
  }

  auto cb = [complete_cb = complete_cb.share()](::bt::hci::CommandChannel::TransactionId id,
                                                const ::bt::hci::EventPacket& event) {
    auto return_params = event.return_params<::bt::hci::ReadScanEnableReturnParams>();
    LogCommandResult(return_params->status, id);
    if (return_params->status != ::bt::hci::StatusCode::kSuccess) {
      complete_cb();
      return;
    }

    if (return_params->scan_enable &
        (::bt::hci::ScanEnableType)::bt::hci::ScanEnableBit::kInquiry) {
      std::cout << "  Inquiry scan: enabled" << std::endl;
    } else {
      std::cout << "  Inquiry scan: disabled" << std::endl;
    }

    if (return_params->scan_enable & (::bt::hci::ScanEnableType)::bt::hci::ScanEnableBit::kPage) {
      std::cout << "  Page scan: enabled" << std::endl;
    } else {
      std::cout << "  Page scan: disabled" << std::endl;
    }

    complete_cb();
  };

  auto packet = ::bt::hci::CommandPacket::New(::bt::hci::kReadScanEnable);
  auto id = SendCommand(cmd_data, std::move(packet), std::move(cb), std::move(complete_cb));
  std::cout << "  Sent HCI_Read_Scan_Enable (id=" << id << ")" << std::endl;

  return true;
}

}  // namespace

void RegisterCommands(const CommandData* cmd_data,
                      ::bluetooth_tools::CommandDispatcher* dispatcher) {
  FX_DCHECK(dispatcher);

#define BIND(handler) std::bind(&handler, cmd_data, std::placeholders::_1, std::placeholders::_2)

  dispatcher->RegisterHandler("version-info", "Send HCI_Read_Local_Version_Information",
                              BIND(HandleVersionInfo));
  dispatcher->RegisterHandler("reset", "Send HCI_Reset", BIND(HandleReset));
  dispatcher->RegisterHandler("read-bdaddr", "Send HCI_Read_BDADDR", BIND(HandleReadBDADDR));
  dispatcher->RegisterHandler("read-local-name", "Send HCI_Read_Local_Name",
                              BIND(HandleReadLocalName));
  dispatcher->RegisterHandler("write-local-name", "Send HCI_Write_Local_Name",
                              BIND(HandleWriteLocalName));
  dispatcher->RegisterHandler("set-event-mask", "Send HCI_Set_Event_Mask",
                              BIND(HandleSetEventMask));
  dispatcher->RegisterHandler("le-set-adv-enable", "Send HCI_LE_Set_Advertising_Enable",
                              BIND(HandleLESetAdvEnable));
  dispatcher->RegisterHandler("le-set-adv-params", "Send HCI_LE_Set_Advertising_Parameters",
                              BIND(HandleLESetAdvParams));
  dispatcher->RegisterHandler("le-set-adv-data", "Send HCI_LE_Set_Advertising_Data",
                              BIND(HandleLESetAdvData));
  dispatcher->RegisterHandler("le-set-scan-params", "Send HCI_LE_Set_Scan_Parameters",
                              BIND(HandleLESetScanParams));
  dispatcher->RegisterHandler("le-scan", "Perform a LE device scan for a limited duration",
                              BIND(HandleLEScan));
  dispatcher->RegisterHandler("scan", "Perform a device scan for a limited duration",
                              BIND(HandleBRScan));
  dispatcher->RegisterHandler("write-page-scan-activity", "Send HCI_Write_Page_Scan_Activity",
                              BIND(HandleWritePageScanActivity));
  dispatcher->RegisterHandler("read-page-scan-activity", "Send HCI_Read_Page_Scan_Activity",
                              BIND(HandleReadPageScanActivity));
  dispatcher->RegisterHandler("write-page-scan-type", "Send HCI_Write_Page_Scan_Type",
                              BIND(HandleWritePageScanType));
  dispatcher->RegisterHandler("read-page-scan-type", "Send HCI_Read_Page_Scan_Type",
                              BIND(HandleReadPageScanType));
  dispatcher->RegisterHandler("write-scan-enable", "Send HCI_Write_Scan_Enable",
                              BIND(HandleWriteScanEnable));
  dispatcher->RegisterHandler("read-scan-enable", "Send HCI_Read_Scan_Enable",
                              BIND(HandleReadScanEnable));
#undef BIND
}

}  // namespace hcitool
