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

#include <lib/gtest/test_loop_fixture.h>

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/test_packets.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_dynamic_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_l2cap.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_signaling_server.h"

namespace bt::testing {
namespace {

l2cap::ChannelParameters kChannelParams;
hci::ConnectionHandle kConnectionHandle = 0x01;
l2cap::CommandId kCommandId = 0x02;
l2cap::PSM kPsm = l2cap::kSDP;
l2cap::ChannelId src_id = l2cap::kFirstDynamicChannelId;

auto SdpErrorResponse(uint16_t t_id, sdp::ErrorCode code) {
  return StaticByteBuffer(0x01, UpperBits(t_id), LowerBits(t_id), 0x00, 0x02,
                          UpperBits(uint16_t(code)), LowerBits(uint16_t(code)));
}

std::vector<sdp::ServiceRecord> GetSPPServiceRecord() {
  sdp::ServiceRecord record;
  record.SetServiceClassUUIDs({sdp::profile::kSerialPort});
  record.AddProtocolDescriptor(sdp::ServiceRecord::kPrimaryProtocolList, sdp::protocol::kL2CAP,
                               sdp::DataElement());
  record.AddProtocolDescriptor(sdp::ServiceRecord::kPrimaryProtocolList, sdp::protocol::kRFCOMM,
                               sdp::DataElement(uint8_t{0}));
  record.AddProfile(sdp::profile::kSerialPort, 1, 2);
  record.AddInfo("en", "FAKE", "", "");
  std::vector<sdp::ServiceRecord> records;
  records.emplace_back(std::move(record));
  return records;
}

std::vector<sdp::ServiceRecord> GetA2DPServiceRecord() {
  sdp::ServiceRecord record;
  record.SetServiceClassUUIDs({sdp::profile::kAudioSink});
  record.AddProtocolDescriptor(sdp::ServiceRecord::kPrimaryProtocolList, sdp::protocol::kL2CAP,
                               sdp::DataElement(l2cap::kAVDTP));
  record.AddProtocolDescriptor(sdp::ServiceRecord::kPrimaryProtocolList, sdp::protocol::kAVDTP,
                               sdp::DataElement(uint16_t{0x0103}));  // Version
  record.AddProfile(sdp::profile::kAdvancedAudioDistribution, 1, 3);
  record.SetAttribute(sdp::kA2DP_SupportedFeatures,
                      sdp::DataElement(uint16_t{0x0001}));  // Headphones
  std::vector<sdp::ServiceRecord> records;
  records.emplace_back(std::move(record));
  return records;
}

#define UINT32_AS_BE_BYTES(x) \
  UpperBits(x >> 16), LowerBits(x >> 16), UpperBits(x & 0xFFFF), LowerBits(x & 0xFFFF)

TEST(TESTING_FakeSdpServerTest, SuccessfulSearch) {
  std::unique_ptr<ByteBuffer> sent_packet;
  auto send_cb = [&sent_packet](auto& buffer) {
    sent_packet = std::make_unique<DynamicByteBuffer>(buffer);
  };
  FakeDynamicChannel channel(kConnectionHandle, kCommandId, src_id, src_id);
  channel.set_send_packet_callback(send_cb);
  channel.set_opened();
  auto sdp_server = FakeSdpServer();

  // Configure the SDP server to provide a response to the search.
  auto NopConnectCallback = [](auto /*channel*/, const sdp::DataElement&) {};
  sdp::Server::RegistrationHandle spp_handle = sdp_server.server()->RegisterService(
      GetSPPServiceRecord(), kChannelParams, NopConnectCallback);
  EXPECT_TRUE(spp_handle);
  sdp::Server::RegistrationHandle a2dp_handle = sdp_server.server()->RegisterService(
      GetA2DPServiceRecord(), kChannelParams, NopConnectCallback);
  EXPECT_TRUE(a2dp_handle);
  const StaticByteBuffer kL2capSearch =
      CreateStaticByteBuffer(0x02,        // SDP_ServiceSearchRequest
                             0x10, 0x01,  // Transaction ID (0x1001)
                             0x00, 0x08,  // Parameter length (8 bytes)
                             // ServiceSearchPattern
                             0x35, 0x03,        // Sequence uint8 3 bytes
                             0x19, 0x01, 0x00,  // UUID: Protocol: L2CAP
                             0xFF, 0xFF,        // MaximumServiceRecordCount: (none)
                             0x00               // Contunuation State: none
      );
  const StaticByteBuffer kL2capSearchResponse = CreateStaticByteBuffer(
      0x03,                             // SDP_ServicesearchResponse
      0x10, 0x01,                       // Transaction ID (0x1001)
      0x00, 0x0D,                       // Parameter length (13 bytes)
      0x00, 0x02,                       // Total service record count: 2
      0x00, 0x02,                       // Current service record count: 2
      UINT32_AS_BE_BYTES(a2dp_handle),  // This list isn't specifically ordered
      UINT32_AS_BE_BYTES(spp_handle),
      0x00  // No continuation state
  );
  sdp_server.HandleSdu(channel.AsWeakPtr(), kL2capSearch);
  EXPECT_TRUE(ContainersEqual(kL2capSearchResponse, *sent_packet));
}

TEST(TESTING_FakeSdpServerTest, ErrorIfTooSmall) {
  std::unique_ptr<ByteBuffer> sent_packet;
  auto send_cb = [&sent_packet](auto& buffer) {
    sent_packet = std::make_unique<DynamicByteBuffer>(buffer);
  };
  FakeDynamicChannel channel(kConnectionHandle, kCommandId, src_id, src_id);
  channel.set_send_packet_callback(send_cb);
  channel.set_opened();
  auto sdp_server = FakeSdpServer();

  // Expect an error response if the packet is too small
  const auto kTooSmall = CreateStaticByteBuffer(0x01,        // SDP_ServiceSearchRequest
                                                0x10, 0x01,  // Transaction ID (0x1001)
                                                0x00, 0x09   // Parameter length (9 bytes)
  );
  const auto kRspTooSmall = SdpErrorResponse(0x1001, sdp::ErrorCode::kInvalidSize);
  sdp_server.HandleSdu(channel.AsWeakPtr(), kTooSmall);
  EXPECT_TRUE(ContainersEqual(kRspTooSmall, *sent_packet));
}

TEST(TESTING_FakeSdpServerTest, RegisterWithL2cap) {
  std::unique_ptr<ByteBuffer> received_packet;
  auto send_cb = [&received_packet](auto conn, auto cid, auto& buffer) {
    received_packet = std::make_unique<DynamicByteBuffer>(buffer);
  };
  auto fake_l2cap = FakeL2cap(send_cb);
  auto sdp_server = std::make_unique<FakeSdpServer>();
  sdp_server->RegisterWithL2cap(&fake_l2cap);
  EXPECT_TRUE(fake_l2cap.ServiceRegisteredForPsm(kPsm));
}

}  // namespace
}  // namespace bt::testing
