// Copyright 2024 The Pigweed Authors
//
// 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
//
//     https://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 "pw_bluetooth_proxy/proxy_host.h"

#include <mutex>

#include "pw_assert/check.h"  // IWYU pragma: keep
#include "pw_bluetooth/hci_common.emb.h"
#include "pw_bluetooth/hci_h4.emb.h"
#include "pw_bluetooth_proxy/emboss_util.h"
#include "pw_bluetooth_proxy/h4_packet.h"
#include "pw_log/log.h"

namespace pw::bluetooth::proxy {

ProxyHost::ProxyHost(
    pw::Function<void(H4PacketWithHci&& packet)>&& send_to_host_fn,
    pw::Function<void(H4PacketWithH4&& packet)>&& send_to_controller_fn,
    uint16_t le_acl_credits_to_reserve)
    : hci_transport_(std::move(send_to_host_fn),
                     std::move(send_to_controller_fn)),
      acl_data_channel_(hci_transport_, le_acl_credits_to_reserve),
      acl_send_pending_(false) {}

void ProxyHost::HandleH4HciFromHost(H4PacketWithH4&& h4_packet) {
  hci_transport_.SendToController(std::move(h4_packet));
}

void ProxyHost::ProcessH4HciFromController(pw::span<uint8_t> hci_buffer) {
  auto event = MakeEmboss<emboss::EventHeaderView>(hci_buffer);
  if (!event.IsComplete()) {
    PW_LOG_ERROR("Buffer is too small for EventHeader. So will not process.");
    return;
  }

  PW_MODIFY_DIAGNOSTICS_PUSH();
  PW_MODIFY_DIAGNOSTIC(ignored, "-Wswitch-enum");
  switch (event.event_code_enum().Read()) {
    case emboss::EventCode::NUMBER_OF_COMPLETED_PACKETS: {
      auto nocp_event =
          MakeEmboss<emboss::NumberOfCompletedPacketsEventWriter>(hci_buffer);
      if (!nocp_event.IsComplete()) {
        PW_LOG_ERROR(
            "Buffer is too small for NUMBER_OF_COMPLETED_PACKETS event. So "
            "will not process.");
        break;
      }
      acl_data_channel_.ProcessNumberOfCompletedPacketsEvent(nocp_event);
      break;
    }
    case emboss::EventCode::DISCONNECTION_COMPLETE: {
      auto dc_event =
          MakeEmboss<emboss::DisconnectionCompleteEventWriter>(hci_buffer);
      if (!dc_event.IsComplete()) {
        PW_LOG_ERROR(
            "Buffer is too small for DISCONNECTION_COMPLETE event. So will not "
            "process.");
        break;
      }
      acl_data_channel_.ProcessDisconnectionCompleteEvent(dc_event);
      break;
    }
    case emboss::EventCode::COMMAND_COMPLETE: {
      ProcessCommandCompleteEvent(hci_buffer);
      break;
    }
    default: {
      PW_LOG_ERROR("Received unexpected HCI event. So will not process.");
      return;
    }
  }
  PW_MODIFY_DIAGNOSTICS_POP();
}

void ProxyHost::ProcessCommandCompleteEvent(pw::span<uint8_t> hci_buffer) {
  auto command_complete_event =
      MakeEmboss<emboss::CommandCompleteEventView>(hci_buffer);
  if (!command_complete_event.IsComplete()) {
    PW_LOG_ERROR(
        "Buffer is too small for COMMAND_COMPLETE event. So will not process.");
    return;
  }

  PW_MODIFY_DIAGNOSTICS_PUSH();
  PW_MODIFY_DIAGNOSTIC(ignored, "-Wswitch-enum");
  switch (command_complete_event.command_opcode_enum().Read()) {
    case emboss::OpCode::LE_READ_BUFFER_SIZE_V1: {
      auto read_event =
          MakeEmboss<emboss::LEReadBufferSizeV1CommandCompleteEventWriter>(
              hci_buffer);
      if (!read_event.IsComplete()) {
        PW_LOG_ERROR(
            "Buffer is too small for LE_READ_BUFFER_SIZE_V1 command complete "
            "event. So will not process.");
        return;
      }
      acl_data_channel_.ProcessLEReadBufferSizeCommandCompleteEvent(read_event);
      break;
    }
    case emboss::OpCode::LE_READ_BUFFER_SIZE_V2: {
      auto read_event =
          MakeEmboss<emboss::LEReadBufferSizeV2CommandCompleteEventWriter>(
              hci_buffer);
      if (!read_event.IsComplete()) {
        PW_LOG_ERROR(
            "Buffer is too small for LE_READ_BUFFER_SIZE_V2 command complete "
            "event. So will not process.");
        return;
      }
      acl_data_channel_.ProcessLEReadBufferSizeCommandCompleteEvent(read_event);
      break;
    }
    default:
      // Nothing to process
      break;
  }
  PW_MODIFY_DIAGNOSTICS_POP();
}

void ProxyHost::HandleH4HciFromController(H4PacketWithHci&& h4_packet) {
  if (h4_packet.GetHciSpan().empty()) {
    PW_LOG_ERROR("Received empty H4 buffer. So will not process.");
  } else if (h4_packet.GetH4Type() == emboss::H4PacketType::EVENT) {
    ProcessH4HciFromController(h4_packet.GetHciSpan());
  }
  hci_transport_.SendToHost(std::move(h4_packet));
}

pw::Status ProxyHost::sendGattNotify(uint16_t connection_handle,
                                     uint16_t attribute_handle,
                                     const pw::span<uint8_t> attribute_value) {
  if (connection_handle > 0x0EFF) {
    PW_LOG_ERROR(
        "Invalid connection handle: %d (max: 0x0EFF). So will not process.",
        connection_handle);
    return pw::Status::InvalidArgument();
  }
  if (attribute_handle == 0) {
    PW_LOG_ERROR("Attribute handle cannot be 0. So will not process.");
    return pw::Status::InvalidArgument();
  }
  if (constexpr uint16_t kMaxAttributeSize =
          kH4BuffSize - 1 - emboss::AttNotifyOverAcl::MinSizeInBytes();
      attribute_value.size() > kMaxAttributeSize) {
    PW_LOG_ERROR("Attribute too large (%zu > %d). So will not process.",
                 attribute_value.size(),
                 kMaxAttributeSize);
    return pw::Status::InvalidArgument();
  }

  H4PacketWithH4 h4_att_notify({});
  {
    std::lock_guard lock(acl_send_mutex_);
    // TODO: https://pwbug.dev/348680331 - Currently ProxyHost only supports 1
    // in-flight ACL send, increase this to support multiple.
    if (acl_send_pending_) {
      return pw::Status::Unavailable();
    }
    acl_send_pending_ = true;

    size_t acl_packet_size =
        emboss::AttNotifyOverAcl::MinSizeInBytes() + attribute_value.size();
    emboss::AttNotifyOverAclWriter att_notify =
        emboss::MakeAttNotifyOverAclView(attribute_value.size(),
                                         H4HciSubspan(h4_buff_).data(),
                                         acl_packet_size);
    if (!att_notify.IsComplete()) {
      PW_LOG_ERROR("Buffer is too small for ATT Notify. So will not send.");
      return pw::Status::InvalidArgument();
    }

    BuildAttNotify(
        att_notify, connection_handle, attribute_handle, attribute_value);

    size_t h4_packet_size = 1 + acl_packet_size;
    H4PacketWithH4 h4_temp(pw::span(h4_buff_.data(), h4_packet_size),
                           [this](const uint8_t* buffer) {
                             std::lock_guard inner_lock(acl_send_mutex_);
                             PW_CHECK_PTR_EQ(
                                 buffer,
                                 h4_buff_.data(),
                                 "Received release callback for buffer that "
                                 "doesn't match our buffer.");
                             PW_LOG_DEBUG("H4 packet release fn called.");
                             acl_send_pending_ = false;
                           });
    h4_temp.SetH4Type(emboss::H4PacketType::ACL_DATA);
    h4_att_notify = std::move(h4_temp);
  }

  // H4 packet is hereby moved. Either ACL data channel will move packet to
  // controller or will be unable to send packet. In either case, packet will be
  // destructed, so its release function will clear the `acl_send_pending` flag.
  if (!acl_data_channel_.SendAcl(std::move(h4_att_notify))) {
    return pw::Status::Unavailable();
  }
  return OkStatus();
}

void ProxyHost::BuildAttNotify(emboss::AttNotifyOverAclWriter att_notify,
                               uint16_t connection_handle,
                               uint16_t attribute_handle,
                               const pw::span<uint8_t> attribute_value) {
  // ACL header
  att_notify.acl_header().handle().Write(connection_handle);
  att_notify.acl_header().packet_boundary_flag().Write(
      emboss::AclDataPacketBoundaryFlag::FIRST_NON_FLUSHABLE);
  att_notify.acl_header().broadcast_flag().Write(
      emboss::AclDataPacketBroadcastFlag::POINT_TO_POINT);
  size_t att_pdu_size =
      emboss::AttHandleValueNtf::MinSizeInBytes() + attribute_value.size();
  att_notify.acl_header().data_total_length().Write(
      emboss::BFrameHeader::IntrinsicSizeInBytes() + att_pdu_size);

  // L2CAP header
  // TODO: https://pwbug.dev/349602172 - Define ATT CID in pw_bluetooth.
  constexpr uint16_t kAttributeProtocolCID = 0x0004;
  att_notify.l2cap_header().channel_id().Write(kAttributeProtocolCID);
  att_notify.l2cap_header().pdu_length().Write(att_pdu_size);

  // ATT PDU
  att_notify.att_handle_value_ntf().attribute_opcode().Write(
      emboss::AttOpcode::ATT_HANDLE_VALUE_NTF);
  att_notify.att_handle_value_ntf().attribute_handle().Write(attribute_handle);
  std::memcpy(att_notify.att_handle_value_ntf()
                  .attribute_value()
                  .BackingStorage()
                  .data(),
              attribute_value.data(),
              attribute_value.size());
}

bool ProxyHost::HasSendAclCapability() const {
  return acl_data_channel_.GetLeAclCreditsToReserve() > 0;
}

uint16_t ProxyHost::GetNumFreeLeAclPackets() const {
  return acl_data_channel_.GetNumFreeLeAclPackets();
}

}  // namespace pw::bluetooth::proxy
