// 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 "command_handler.h"

namespace bt::l2cap::internal {

bool CommandHandler::Response::ParseReject(const ByteBuffer& rej_payload_buf) {
  if (rej_payload_buf.size() < sizeof(CommandRejectPayload)) {
    bt_log(DEBUG, "l2cap", "cmd: ignoring malformed Command Reject, size %zu (expected >= %zu)",
           rej_payload_buf.size(), sizeof(CommandRejectPayload));
    return false;
  }
  auto& rej_payload = rej_payload_buf.As<CommandRejectPayload>();
  reject_reason_ = static_cast<RejectReason>(letoh16(rej_payload.reason));

  if (reject_reason() == RejectReason::kInvalidCID) {
    if (rej_payload_buf.size() - sizeof(CommandRejectPayload) < sizeof(InvalidCIDPayload)) {
      bt_log(DEBUG, "l2cap",
             "cmd: ignoring malformed Command Reject Invalid Channel ID, size %zu (expected %zu)",
             rej_payload_buf.size(), sizeof(CommandRejectPayload) + sizeof(InvalidCIDPayload));
      return false;
    }
    auto& invalid_cid_payload =
        rej_payload_buf.view(sizeof(CommandRejectPayload)).As<InvalidCIDPayload>();
    remote_cid_ = letoh16(invalid_cid_payload.src_cid);
    local_cid_ = letoh16(invalid_cid_payload.dst_cid);
  }

  return true;
}

bool CommandHandler::DisconnectionResponse::Decode(const ByteBuffer& payload_buf) {
  auto& disconn_rsp_payload = payload_buf.As<PayloadT>();
  local_cid_ = letoh16(disconn_rsp_payload.src_cid);
  remote_cid_ = letoh16(disconn_rsp_payload.dst_cid);
  return true;
}

CommandHandler::Responder::Responder(SignalingChannel::Responder* sig_responder,
                                     ChannelId local_cid, ChannelId remote_cid)
    : sig_responder_(sig_responder), local_cid_(local_cid), remote_cid_(remote_cid) {}

void CommandHandler::Responder::RejectNotUnderstood() { sig_responder_->RejectNotUnderstood(); }

void CommandHandler::Responder::RejectInvalidChannelId() {
  sig_responder_->RejectInvalidChannelId(local_cid(), remote_cid());
}

bool CommandHandler::SendDisconnectionRequest(ChannelId remote_cid, ChannelId local_cid,
                                              DisconnectionResponseCallback cb) {
  auto on_discon_rsp = BuildResponseHandler<DisconnectionResponse>(std::move(cb));

  DisconnectionRequestPayload payload = {htole16(remote_cid), htole16(local_cid)};
  return sig()->SendRequest(kDisconnectionRequest, BufferView(&payload, sizeof(payload)),
                            std::move(on_discon_rsp));
}

void CommandHandler::ServeDisconnectionRequest(DisconnectionRequestCallback cb) {
  auto on_discon_req = [cb = std::move(cb)](const ByteBuffer& request_payload,
                                            SignalingChannel::Responder* sig_responder) {
    if (request_payload.size() != sizeof(DisconnectionRequestPayload)) {
      bt_log(DEBUG, "l2cap", "cmd: rejecting malformed Disconnection Request, size %zu",
             request_payload.size());
      sig_responder->RejectNotUnderstood();
      return;
    }

    const auto& discon_req = request_payload.As<DisconnectionRequestPayload>();
    const ChannelId local_cid = letoh16(discon_req.dst_cid);
    const ChannelId remote_cid = letoh16(discon_req.src_cid);
    DisconnectionResponder responder(sig_responder, local_cid, remote_cid);
    cb(local_cid, remote_cid, &responder);
  };

  sig()->ServeRequest(kDisconnectionRequest, std::move(on_discon_req));
}

CommandHandler::CommandHandler(SignalingChannelInterface* sig, fit::closure request_fail_callback)
    : sig_(sig), request_fail_callback_(std::move(request_fail_callback)) {
  ZX_ASSERT(sig_);
}

}  // namespace bt::l2cap::internal
