// Copyright 2018 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/sdp/server.h"

#include "gtest/gtest.h"
#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"
#include "src/connectivity/bluetooth/core/bt-host/data/fake_domain.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/fake_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap.h"
#include "src/connectivity/bluetooth/core/bt-host/sdp/pdu.h"
#include "src/connectivity/bluetooth/core/bt-host/sdp/status.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller.h"
#include "src/connectivity/bluetooth/core/bt-host/testing/fake_controller_test.h"

namespace bt {
namespace sdp {
namespace {

using bt::testing::FakeController;

using TestingBase = bt::testing::FakeControllerTest<FakeController>;

constexpr hci::ConnectionHandle kTestHandle1 = 1;
constexpr hci::ConnectionHandle kTestHandle2 = 2;

void NopConnectCallback(zx::socket, hci::ConnectionHandle, const DataElement&) {
}

class SDP_ServerTest : public TestingBase {
 public:
  SDP_ServerTest() = default;
  ~SDP_ServerTest() = default;

 protected:
  void SetUp() override {
    l2cap_ = data::testing::FakeDomain::Create();
    l2cap_->set_channel_callback(
        [this](auto fake_chan) { channel_ = std::move(fake_chan); });
    l2cap_->Initialize();
    l2cap_->AddACLConnection(kTestHandle1, hci::Connection::Role::kSlave,
                             nullptr, nullptr, nullptr);
    l2cap_->AddACLConnection(kTestHandle2, hci::Connection::Role::kSlave,
                             nullptr, nullptr, nullptr);
    server_ = std::make_unique<Server>(l2cap_);
  }

  void TearDown() override {
    channel_ = nullptr;
    server_ = nullptr;
    l2cap_ = nullptr;
  }

  Server* server() const { return server_.get(); }

  fbl::RefPtr<data::testing::FakeDomain> l2cap() const { return l2cap_; }

  fbl::RefPtr<l2cap::testing::FakeChannel> fake_chan() const {
    return channel_;
  }

  bool Expect(const ByteBuffer& expected) {
    if (!fake_chan()) {
      bt_log(ERROR, "unittest", "no channel, failing!");
      return false;
    }

    bool success = false;
    auto cb = [&expected, &success](auto cb_packet) {
      success = ContainersEqual(expected, *cb_packet);
    };

    fake_chan()->SetSendCallback(cb, dispatcher());
    RunLoopUntilIdle();

    return success;
  }

  bool ReceiveAndExpect(const ByteBuffer& packet,
                        const ByteBuffer& expected_response) {
    if (!fake_chan()) {
      bt_log(ERROR, "unittest", "no channel, failing!");
      return false;
    }

    fake_chan()->Receive(packet);

    return Expect(expected_response);
  }

  ServiceHandle AddSPP(sdp::Server::ConnectCallback cb = NopConnectCallback) {
    ServiceRecord record;

    record.SetServiceClassUUIDs({profile::kSerialPort});
    record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                 protocol::kL2CAP, DataElement());
    record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                 protocol::kRFCOMM, DataElement(uint8_t(0)));
    record.AddProfile(profile::kSerialPort, 1, 2);
    record.AddInfo("en", "FAKE", "", "");
    ServiceHandle handle =
        server()->RegisterService(std::move(record), std::move(cb));
    EXPECT_TRUE(handle);
    return handle;
  }

  ServiceHandle AddA2DPSink(
      sdp::Server::ConnectCallback cb = NopConnectCallback) {
    ServiceRecord record;
    record.SetServiceClassUUIDs({profile::kAudioSink});
    record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                 protocol::kL2CAP, DataElement(l2cap::kAVDTP));
    record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                 protocol::kAVDTP,
                                 DataElement(uint16_t(0x0103)));  // Version
    record.AddProfile(profile::kAdvancedAudioDistribution, 1, 3);
    record.SetAttribute(kA2DP_SupportedFeatures,
                        DataElement(uint16_t(0x0001)));  // Headphones
    ServiceHandle handle =
        server()->RegisterService(std::move(record), std::move(cb));
    EXPECT_TRUE(handle);
    return handle;
  }

 private:
  fbl::RefPtr<l2cap::testing::FakeChannel> channel_;
  fbl::RefPtr<data::testing::FakeDomain> l2cap_;
  std::unique_ptr<Server> server_;
};

constexpr l2cap::ChannelId kSdpChannel = 0x0041;

#define SDP_ERROR_RSP(t_id, code)                                            \
  CreateStaticByteBuffer(0x01, UpperBits(t_id), LowerBits(t_id), 0x00, 0x02, \
                         UpperBits(uint16_t(code)),                          \
                         LowerBits(uint16_t(code)));

// Test:
//  - Accepts channels and holds channel open correctly.
//  - Packets that are the wrong length are responded to with kInvalidSize
//  - Answers with the same TransactionID as sent
TEST_F(SDP_ServerTest, BasicError) {
  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kSDP, kSdpChannel,
                                      0x0bad);
  RunLoopUntilIdle();
  ASSERT_TRUE(fake_chan());
  EXPECT_TRUE(fake_chan()->activated());

  const auto kRspErrSize = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);

  const auto kTooSmall =
      CreateStaticByteBuffer(0x01,        // SDP_ServiceSearchRequest
                             0x10, 0x01,  // Transaction ID (0x1001)
                             0x00, 0x09   // Parameter length (9 bytes)
      );

  const auto kRspTooSmall = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);

  const auto kTooBig =
      CreateStaticByteBuffer(0x01,             // SDP_ServiceSearchRequest
                             0x20, 0x10,       // Transaction ID (0x2010)
                             0x00, 0x02,       // Parameter length (2 bytes)
                             0x01, 0x02, 0x03  // 3 bytes of parameters
      );

  const auto kRspTooBig = SDP_ERROR_RSP(0x2010, ErrorCode::kInvalidSize);

  EXPECT_TRUE(ReceiveAndExpect(kTooSmall, kRspTooSmall));
  EXPECT_TRUE(ReceiveAndExpect(kTooBig, kRspTooBig));

  const auto kRspInvalidSyntax =
      SDP_ERROR_RSP(0x2010, ErrorCode::kInvalidRequestSyntax);

  // Responses aren't valid requests
  EXPECT_TRUE(ReceiveAndExpect(kRspTooBig, kRspInvalidSyntax));
}

// Test:
//  - Passes an initialized ServiceRecord that has a matching SericeHandle
//  - Doesn't add a service that doesn't contain a ServiceClassIDList
//  - Adds a service that is valid.
//  - Services can be Unregistered.
TEST_F(SDP_ServerTest, RegisterService) {
  EXPECT_FALSE(server()->RegisterService(ServiceRecord(), {}));

  ServiceRecord record;
  record.SetAttribute(kServiceClassIdList, DataElement(uint16_t(42)));
  EXPECT_FALSE(server()->RegisterService(std::move(record), {}));

  ServiceRecord has_handle;
  has_handle.SetHandle(42);
  EXPECT_FALSE(server()->RegisterService(std::move(has_handle), {}));

  ServiceRecord valid;
  valid.SetServiceClassUUIDs({profile::kAVRemoteControl});
  ServiceHandle handle = server()->RegisterService(std::move(valid), {});

  EXPECT_TRUE(handle);

  EXPECT_TRUE(server()->UnregisterService(handle));
  EXPECT_FALSE(server()->UnregisterService(handle));
}

TEST_F(SDP_ServerTest, PSMVerification) {
  ServiceRecord no_psm;
  no_psm.SetServiceClassUUIDs({profile::kAVRemoteControl});
  no_psm.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                               protocol::kL2CAP, DataElement());

  EXPECT_FALSE(server()->RegisterService(std::move(no_psm), {}));

  ServiceRecord psm_wrong_argtype;
  psm_wrong_argtype.SetServiceClassUUIDs({profile::kAVRemoteControl});
  psm_wrong_argtype.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                          protocol::kL2CAP,
                                          DataElement(bool(true)));

  EXPECT_FALSE(server()->RegisterService(std::move(psm_wrong_argtype), {}));

  ServiceRecord psm_rfcomm;
  psm_rfcomm.SetServiceClassUUIDs({profile::kAVRemoteControl});
  psm_rfcomm.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                   protocol::kL2CAP, DataElement());
  // Don't need an argument for RFCOMM, it will be auto-assigned.
  psm_rfcomm.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                   protocol::kRFCOMM, DataElement());

  EXPECT_TRUE(
      server()->RegisterService(std::move(psm_rfcomm), NopConnectCallback));

  // Another RFCOMM is also fine.
  ServiceRecord psm_rfcomm2;
  psm_rfcomm2.SetServiceClassUUIDs({profile::kAVRemoteControl});
  psm_rfcomm2.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                    protocol::kL2CAP, DataElement());
  // Don't need an argument for RFCOMM, it will be auto-assigned.
  psm_rfcomm2.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                    protocol::kRFCOMM, DataElement());

  EXPECT_TRUE(
      server()->RegisterService(std::move(psm_rfcomm2), NopConnectCallback));

  ServiceRecord psm_ok;
  psm_ok.SetServiceClassUUIDs({profile::kAVRemoteControl});
  psm_ok.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                               protocol::kL2CAP, DataElement(uint16_t(500)));

  auto handle =
      server()->RegisterService(std::move(psm_ok), NopConnectCallback);
  EXPECT_TRUE(handle);

  ServiceRecord psm_duplicate;
  psm_duplicate.SetServiceClassUUIDs({profile::kAVRemoteControl});
  psm_duplicate.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                      protocol::kL2CAP,
                                      DataElement(uint16_t(500)));

  EXPECT_FALSE(
      server()->RegisterService(std::move(psm_duplicate), NopConnectCallback));

  // Unregistering allows us to re-register with PSM.
  server()->UnregisterService(handle);
  ServiceRecord psm_readd;
  psm_readd.SetServiceClassUUIDs({profile::kAVRemoteControl});
  psm_readd.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                  protocol::kL2CAP, DataElement(uint16_t(500)));

  EXPECT_TRUE(
      server()->RegisterService(std::move(psm_readd), NopConnectCallback));

  // TODO(NET-1417): test that new connections to the PSM get delivered once
  // they are deliverable
}

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

// Test ServiceSearchRequest:
//  - returns services with the UUID included
//  - doesn't return services that don't have the UUID
//  - fails when there are no items or too many items in the search
//  - doesn't return more than the max requested
TEST_F(SDP_ServerTest, ServiceSearchRequest) {
  ServiceHandle spp_handle = AddSPP();
  ServiceHandle a2dp_handle = AddA2DPSink();

  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kSDP, kSdpChannel,
                                      0x0bad);
  RunLoopUntilIdle();

  const auto 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
      );

  ServiceSearchRequest search_req;
  EXPECT_FALSE(search_req.valid());
  EXPECT_EQ(nullptr, search_req.GetPDU(0x1001));

  search_req.set_search_pattern({protocol::kL2CAP});

  auto pdu = search_req.GetPDU(0x1001);
  EXPECT_NE(nullptr, pdu);

  EXPECT_TRUE(ContainersEqual(kL2capSearch, *pdu));

  const auto 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(spp_handle),  // This list isn't specifically ordered
      UINT32_AS_BE_BYTES(a2dp_handle),
      0x00  // No continuation state
  );

  bool recv = false;
  std::vector<ServiceHandle> handles;
  TransactionId tid;
  auto cb = [&recv, &handles, &tid](auto cb_packet) {
    EXPECT_LE(sizeof(Header), cb_packet->size());
    PacketView<Header> packet(cb_packet.get());
    EXPECT_EQ(kServiceSearchResponse, packet.header().pdu_id);
    tid = betoh16(packet.header().tid);
    uint16_t len = betoh16(packet.header().param_length);
    bt_log(SPEW, "unittest", "resize packet to %d", len);
    packet.Resize(len);
    ServiceSearchResponse resp;
    auto status = resp.Parse(packet.payload_data());
    EXPECT_TRUE(status);
    handles = resp.service_record_handle_list();
    recv = true;
  };

  fake_chan()->SetSendCallback(cb, dispatcher());
  fake_chan()->Receive(kL2capSearch);
  RunLoopUntilIdle();

  EXPECT_TRUE(recv);
  EXPECT_EQ(0x1001, tid);
  EXPECT_EQ(2u, handles.size());
  EXPECT_NE(handles.end(),
            std::find(handles.begin(), handles.end(), spp_handle));
  EXPECT_NE(handles.end(),
            std::find(handles.begin(), handles.end(), a2dp_handle));

  const auto kInvalidNoItems =
      CreateStaticByteBuffer(0x02,        // SDP_ServiceSearchRequest
                             0x10, 0xA1,  // Transaction ID (0x10A1)
                             0x00, 0x05,  // Parameter length (5 bytes)
                             // ServiceSearchPattern
                             0x35, 0x00,  // Sequence uint8 0 bytes
                             0xFF, 0xFF,  // MaximumServiceRecordCount: (none)
                             0x00         // Contunuation State: none
      );

  const auto kRspErrSyntax =
      SDP_ERROR_RSP(0x10A1, ErrorCode::kInvalidRequestSyntax);

  EXPECT_TRUE(ReceiveAndExpect(kInvalidNoItems, kRspErrSyntax));

  const auto kInvalidTooManyItems = CreateStaticByteBuffer(
      0x02,        // SDP_ServiceSearchRequest
      0x10, 0xA1,  // Transaction ID (0x10B1)
      0x00, 0x2C,  // Parameter length (44 bytes)
      // ServiceSearchPattern
      0x35, 0x27,        // Sequence uint8 27 bytes
      0x19, 0x30, 0x01,  // 13 UUIDs in the search
      0x19, 0x30, 0x02, 0x19, 0x30, 0x03, 0x19, 0x30, 0x04, 0x19, 0x30, 0x05,
      0x19, 0x30, 0x06, 0x19, 0x30, 0x07, 0x19, 0x30, 0x08, 0x19, 0x30, 0x09,
      0x19, 0x30, 0x10, 0x19, 0x30, 0x11, 0x19, 0x30, 0x12, 0x19, 0x30, 0x13,
      0xFF, 0xFF,  // MaximumServiceRecordCount: (none)
      0x00         // Contunuation State: none
  );

  EXPECT_TRUE(ReceiveAndExpect(kInvalidTooManyItems, kRspErrSyntax));
}

// Test ServiceSearchRequest:
//  - doesn't return more than the max requested
TEST_F(SDP_ServerTest, ServiceSearchRequestOneOfMany) {
  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kSDP, kSdpChannel,
                                      0x0bad);
  RunLoopUntilIdle();

  ServiceHandle spp_handle = AddSPP();
  ServiceHandle a2dp_handle = AddA2DPSink();

  bool recv = false;
  std::vector<ServiceHandle> handles;
  TransactionId tid;
  auto cb = [&recv, &handles, &tid](auto cb_packet) {
    EXPECT_LE(sizeof(Header), cb_packet->size());
    PacketView<Header> packet(cb_packet.get());
    EXPECT_EQ(kServiceSearchResponse, packet.header().pdu_id);
    tid = betoh16(packet.header().tid);
    uint16_t len = betoh16(packet.header().param_length);
    bt_log(SPEW, "unittests", "resizing packet to %d", len);
    packet.Resize(len);
    ServiceSearchResponse resp;
    auto status = resp.Parse(packet.payload_data());
    EXPECT_TRUE(status);
    handles = resp.service_record_handle_list();
    recv = true;
  };

  const auto kL2capSearchOne =
      CreateStaticByteBuffer(0x02,        // SDP_ServiceSearchRequest
                             0x10, 0xC1,  // Transaction ID (0x10C1)
                             0x00, 0x08,  // Parameter length (8 bytes)
                             // ServiceSearchPattern
                             0x35, 0x03,        // Sequence uint8 3 bytes
                             0x19, 0x01, 0x00,  // UUID: Protocol: L2CAP
                             0x00, 0x01,        // MaximumServiceRecordCount: 1
                             0x00               // Contunuation State: none
      );

  handles.clear();
  recv = false;

  fake_chan()->SetSendCallback(cb, dispatcher());
  fake_chan()->Receive(kL2capSearchOne);
  RunLoopUntilIdle();

  EXPECT_TRUE(recv);
  EXPECT_EQ(0x10C1, tid);
  EXPECT_EQ(1u, handles.size());
  bool found_spp =
      std::find(handles.begin(), handles.end(), spp_handle) != handles.end();
  bool found_a2dp =
      std::find(handles.begin(), handles.end(), a2dp_handle) != handles.end();
  EXPECT_TRUE(found_spp || found_a2dp);
}

// Test:
//  - Answers ServiceAttributeRequest correctly
//  - Continuation state is generated correctly re:
//    MaximumAttributeListByteCount
//  - Valid Continuation state continues response
TEST_F(SDP_ServerTest, ServiceAttributeRequest) {
  ServiceRecord record;
  record.SetServiceClassUUIDs({profile::kAVRemoteControl});
  record.SetAttribute(0xf00d, DataElement(uint32_t(0xfeedbeef)));
  record.SetAttribute(0xf000, DataElement(uint32_t(0x01234567)));

  ServiceHandle handle = server()->RegisterService(std::move(record), {});

  EXPECT_TRUE(handle);

  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kSDP, kSdpChannel,
                                      0x0bad);
  RunLoopUntilIdle();

  const auto kRequestAttr = CreateStaticByteBuffer(
      0x04,                        // SDP_ServiceAttritbuteRequest
      0x10, 0x01,                  // Transaction ID (0x1001)
      0x00, 0x11,                  // Parameter length (17 bytes)
      UINT32_AS_BE_BYTES(handle),  // ServiceRecordHandle
      0x00, 0x0A,                  // MaximumAttributeByteCount (10 bytes max)
      // AttributeIDList
      0x35, 0x08,  // Sequence uint8 8 bytes
      0x09,        // uint16_t, single attribute
      0x00, 0x01,  // ServiceClassIDList
      0x0A,        // uint32_t, which is a range (0x3000 - 0xf000)
      0x30, 0x00,  // low end of range
      0xf0, 0x00,  // high end of range
      0x00         // Contunuation State: none
  );

  size_t received = 0;

  ServiceAttributeResponse rsp;

  auto send_cb = [this, handle, &rsp, &received](auto cb_packet) {
    EXPECT_LE(sizeof(Header), cb_packet->size());
    PacketView<sdp::Header> packet(cb_packet.get());
    ASSERT_EQ(0x05, packet.header().pdu_id);
    uint16_t len = betoh16(packet.header().param_length);
    EXPECT_LE(len, 0x11);  // 10 + 2 (byte count) + 5 (cont state)
    packet.Resize(len);
    Status st = rsp.Parse(packet.payload_data());
    if (received == 0) {
      // Server should have split this into more than one response.
      EXPECT_FALSE(st);
      EXPECT_EQ(HostError::kInProgress, st.error());
      EXPECT_FALSE(rsp.complete());
    }
    received++;
    if (!st && (st.error() != HostError::kInProgress)) {
      // This isn't a valid packet and we shouldn't try to get
      // a continuation.
      return;
    }
    if (!rsp.complete()) {
      // Repeat the request with the continuation state if it was returned.
      auto continuation = rsp.ContinuationState();
      uint8_t cont_size = continuation.size();
      EXPECT_NE(0u, cont_size);
      // Make another request with the continutation data.
      size_t param_size = 17 + cont_size;
      auto kContinuedRequestAttrStart = CreateStaticByteBuffer(
          0x04,  // SDP_ServiceAttributeRequest
          0x10, static_cast<uint8_t>(received + 1), UpperBits(param_size),
          LowerBits(param_size),       // Parameter length
          UINT32_AS_BE_BYTES(handle),  // ServiceRecordHandle
          0x00, 0x0A,  // MaximumAttributeByteCount (10 bytes max)
          // AttributeIDList
          0x35, 0x08,  // Sequence uint8 8 bytes
          0x09,        // uint16_t, single attribute
          0x00, 0x01,  // ServiceClassIDList
          0x0A,        // uint32_t, which is a range (0x3000 - 0xf000)
          0x30, 0x00,  // low end of range
          0xf0, 0x00   // high end of range
      );
      DynamicByteBuffer req(kContinuedRequestAttrStart.size() +
                            sizeof(uint8_t) + cont_size);

      kContinuedRequestAttrStart.Copy(&req);
      req.Write(&cont_size, sizeof(uint8_t), kContinuedRequestAttrStart.size());
      req.Write(continuation,
                kContinuedRequestAttrStart.size() + sizeof(uint8_t));

      fake_chan()->Receive(req);
    }
  };

  fake_chan()->SetSendCallback(send_cb, dispatcher());
  fake_chan()->Receive(kRequestAttr);
  RunLoopUntilIdle();

  EXPECT_GE(received, 1u);
  const auto& attrs = rsp.attributes();
  EXPECT_EQ(2u, attrs.size());
  EXPECT_NE(attrs.end(), attrs.find(kServiceClassIdList));
  EXPECT_NE(attrs.end(), attrs.find(0xf000));

  const auto kInvalidRangeOrder = CreateStaticByteBuffer(
      0x04,                        // SDP_ServiceAttritbuteRequest
      0xE0, 0x01,                  // Transaction ID (0xE001)
      0x00, 0x11,                  // Parameter length (17 bytes)
      UINT32_AS_BE_BYTES(handle),  // ServiceRecordHandle
      0x00, 0x0A,                  // MaximumAttributeByteCount (10 bytes max)
      // AttributeIDList
      0x35, 0x08,  // Sequence uint8 8 bytes
      0x09,        // uint16_t, single attribute
      0x00, 0x01,  // ServiceClassIDList
      0x0A,        // uint32_t, which is a range (0x3000 - 0xf000)
      0xf0, 0x00,  // low end of range
      0x30, 0x00,  // high end of range
      0x00         // Contunuation State: none
  );

  const auto kRspErrSyntax =
      SDP_ERROR_RSP(0xE001, ErrorCode::kInvalidRequestSyntax);

  EXPECT_TRUE(ReceiveAndExpect(kInvalidRangeOrder, kRspErrSyntax));

  const auto kInvalidMaxBytes = CreateStaticByteBuffer(
      0x04,                        // SDP_ServiceAttritbuteRequest
      0xE0, 0x02,                  // Transaction ID (0xE001)
      0x00, 0x0C,                  // Parameter length (12 bytes)
      UINT32_AS_BE_BYTES(handle),  // ServiceRecordHandle
      0x00, 0x05,                  // MaximumAttributeByteCount (5 bytes max)
      // AttributeIDList
      0x35, 0x03,  // Sequence uint8 3 bytes
      0x09,        // uint16_t, single attribute
      0x00, 0x01,  // ServiceClassIDList
      0x00         // Contunuation State: none
  );

  const auto kRspErrSyntax2 =
      SDP_ERROR_RSP(0xE002, ErrorCode::kInvalidRequestSyntax);

  EXPECT_TRUE(ReceiveAndExpect(kInvalidMaxBytes, kRspErrSyntax2));
}

// Test:
//  - Answers ServiceSearchAttributeRequest correctly
//  - Continuation state is generated correctly re:
//    MaximumAttributeListsByteCount
//  - Valid Continuation state continues response
TEST_F(SDP_ServerTest, SearchAttributeRequest) {
  ServiceRecord record1;
  record1.SetServiceClassUUIDs({profile::kAVRemoteControl});
  record1.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                protocol::kL2CAP, DataElement(uint16_t(500)));
  record1.SetAttribute(0xf00d, DataElement(uint32_t(0xfeedbeef)));
  record1.SetAttribute(0xf000, DataElement(uint32_t(0x01234567)));

  ServiceHandle handle1 =
      server()->RegisterService(std::move(record1), NopConnectCallback);

  EXPECT_TRUE(handle1);

  ServiceRecord record2;
  record2.SetServiceClassUUIDs({profile::kAVRemoteControl});
  record2.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
                                protocol::kL2CAP, DataElement(uint16_t(501)));
  ServiceHandle handle2 =
      server()->RegisterService(std::move(record2), NopConnectCallback);

  EXPECT_TRUE(handle2);

  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kSDP, kSdpChannel,
                                      0x0bad);
  RunLoopUntilIdle();

  const auto kRequestAttr = CreateStaticByteBuffer(
      0x06,        // SDP_ServiceAttritbuteRequest
      0x10, 0x01,  // Transaction ID (0x1001)
      0x00, 0x12,  // Parameter length (18 bytes)
      // ServiceSearchPattern
      0x35, 0x03,        // Sequence uint8 3 bytes
      0x19, 0x01, 0x00,  // UUID: Protocol: L2CAP
      0x00, 0x0A,        // MaximumAttributeByteCount (10 bytes max)
      // AttributeIDList
      0x35, 0x08,  // Sequence uint8 8 bytes
      0x09,        // uint16_t, single attribute
      0x00, 0x00,  // ServiceRecordHandle
      0x0A,        // uint32_t, which is a range (0x3000 - 0xf000)
      0x30, 0x00,  // low end of range
      0xf0, 0x00,  // high end of range
      0x00         // Contunuation State: none
  );

  size_t received = 0;

  ServiceSearchAttributeResponse rsp;

  auto send_cb = [this, &rsp, &received](auto cb_packet) {
    EXPECT_LE(sizeof(Header), cb_packet->size());
    PacketView<sdp::Header> packet(cb_packet.get());
    ASSERT_EQ(0x07, packet.header().pdu_id);
    uint16_t len = betoh16(packet.header().param_length);
    EXPECT_LE(len, 0x11);  // 2 (byte count) + 10 (max len) + 5 (cont state)
    packet.Resize(len);
    Status st = rsp.Parse(packet.payload_data());
    if (received == 0) {
      // Server should have split this into more than one response.
      EXPECT_FALSE(st);
      EXPECT_EQ(HostError::kInProgress, st.error());
      EXPECT_FALSE(rsp.complete());
    }
    received++;
    if (!st && (st.error() != HostError::kInProgress)) {
      // This isn't a valid packet and we shouldn't try to get
      // a continuation.
      return;
    }
    if (!rsp.complete()) {
      // Repeat the request with the continuation state if it was returned.
      auto continuation = rsp.ContinuationState();
      uint8_t cont_size = continuation.size();
      EXPECT_NE(0u, cont_size);
      // Make another request with the continutation data.
      size_t param_size = 18 + cont_size;
      auto kContinuedRequestAttrStart = CreateStaticByteBuffer(
          0x06,  // SDP_ServiceAttributeRequest
          0x10, static_cast<uint8_t>(received + 1),      // Transaction ID
          UpperBits(param_size), LowerBits(param_size),  // Parameter length
          0x35, 0x03,        // Sequence uint8 3 bytes
          0x19, 0x01, 0x00,  // SearchPattern: L2CAP
          0x00, 0x0A,        // MaximumAttributeByteCount (10 bytes max)
          // AttributeIDList
          0x35, 0x08,  // Sequence uint8 8 bytes
          0x09,        // uint16_t, single attribute
          0x00, 0x00,  // ServiceRecordHandle
          0x0A,        // uint32_t, which is a range (0x3000 - 0xf000)
          0x30, 0x00,  // low end of range
          0xf0, 0x00   // high end of range
      );
      DynamicByteBuffer req(kContinuedRequestAttrStart.size() +
                            sizeof(uint8_t) + cont_size);

      kContinuedRequestAttrStart.Copy(&req);
      req.Write(&cont_size, sizeof(uint8_t), kContinuedRequestAttrStart.size());
      req.Write(continuation,
                kContinuedRequestAttrStart.size() + sizeof(uint8_t));

      fake_chan()->Receive(req);
    }
  };

  fake_chan()->SetSendCallback(send_cb, dispatcher());
  fake_chan()->Receive(kRequestAttr);
  RunLoopUntilIdle();

  EXPECT_GE(received, 1u);
  // We should receive both of our entered records.
  EXPECT_EQ(2u, rsp.num_attribute_lists());
  for (size_t i = 0; i < rsp.num_attribute_lists(); i++) {
    const auto& attrs = rsp.attributes(i);
    // Every service has a record handle
    auto handle_it = attrs.find(kServiceRecordHandle);
    EXPECT_NE(attrs.end(), handle_it);
    ServiceHandle received_handle = *handle_it->second.Get<uint32_t>();
    if (received_handle == handle1) {
      // The first service also has another attribute we should find.
      EXPECT_EQ(2u, attrs.size());
      EXPECT_NE(attrs.end(), attrs.find(0xf000));
    }
  }

  const auto kInvalidRangeOrder = CreateStaticByteBuffer(
      0x06,                          // SDP_ServiceAttritbuteRequest
      0xE0, 0x01,                    // Transaction ID (0xE001)
      0x00, 0x12,                    // Parameter length (18 bytes)
      0x35, 0x03, 0x19, 0x01, 0x00,  // SearchPattern: L2CAP
      0x00, 0x0A,                    // MaximumAttributeByteCount (10 bytes max)
      // AttributeIDList
      0x35, 0x08,  // Sequence uint8 8 bytes
      0x09,        // uint16_t, single attribute
      0x00, 0x01,  // ServiceClassIDList
      0x0A,        // uint32_t, which is a range (0x3000 - 0xf000)
      0xf0, 0x00,  // low end of range
      0x30, 0x00,  // high end of range
      0x00         // Contunuation State: none
  );

  const auto kRspErrSyntax =
      SDP_ERROR_RSP(0xE001, ErrorCode::kInvalidRequestSyntax);

  EXPECT_TRUE(ReceiveAndExpect(kInvalidRangeOrder, kRspErrSyntax));

  const auto kInvalidMaxBytes = CreateStaticByteBuffer(
      0x04,                          // SDP_ServiceAttritbuteRequest
      0xE0, 0x02,                    // Transaction ID (0xE002)
      0x00, 0x0D,                    // Parameter length (13 bytes)
      0x35, 0x03, 0x19, 0x01, 0x00,  // SearchPattern: L2CAP
      0x00, 0x05,                    // MaximumAttributeByteCount (5 bytes max)
      // AttributeIDList
      0x35, 0x03,  // Sequence uint8 3 bytes
      0x09,        // uint16_t, single attribute
      0x00, 0x01,  // ServiceClassIDList
      0x00         // Contunuation State: none
  );

  const auto kRspErrSyntax2 =
      SDP_ERROR_RSP(0xE002, ErrorCode::kInvalidRequestSyntax);

  EXPECT_TRUE(ReceiveAndExpect(kInvalidMaxBytes, kRspErrSyntax2));
}

TEST_F(SDP_ServerTest, ConnectionCallbacks) {
  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kSDP, kSdpChannel,
                                      0x0bad);
  RunLoopUntilIdle();

  std::vector<zx::socket> socks;
  hci::ConnectionHandle latest_handle;

  // Register a service
  AddA2DPSink([&socks, &latest_handle](zx::socket incoming_sock, auto handle,
                                       const auto& protocol) {
    bt_log(SPEW, "test", "Got socket for the a2dp sink");
    socks.emplace_back(std::move(incoming_sock));
    latest_handle = handle;
  });

  // Connect to the service
  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kAVDTP,
                                      kSdpChannel + 1, 0x0b00);
  RunLoopUntilIdle();

  // It should get a callback with a socket
  EXPECT_EQ(1u, socks.size());
  EXPECT_EQ(kTestHandle1, latest_handle);

  // Connect to the same service again with the same PSM (on a different
  // connection, it should still work)
  l2cap()->TriggerInboundL2capChannel(kTestHandle2, l2cap::kAVDTP,
                                      kSdpChannel + 2, 0x0b01);
  RunLoopUntilIdle();

  ASSERT_EQ(2u, socks.size());
  EXPECT_EQ(kTestHandle2, latest_handle);
  EXPECT_NE(socks.front(), socks.back());
}

// Browse Group gets set correctly
TEST_F(SDP_ServerTest, BrowseGroup) {
  AddA2DPSink();

  l2cap()->TriggerInboundL2capChannel(kTestHandle1, l2cap::kSDP, kSdpChannel,
                                      0x0bad);
  RunLoopUntilIdle();

  const auto kRequestAttr =
      CreateStaticByteBuffer(0x06,        // SDP_ServiceAttritbuteRequest
                             0x10, 0x01,  // Transaction ID (0x1001)
                             0x00, 0x0D,  // Parameter length (12 bytes)
                             // ServiceSearchPattern
                             0x35, 0x03,        // Sequence uint8 3 bytes
                             0x19, 0x01, 0x00,  // UUID: Protocol: L2CAP
                             0xFF, 0xFF,  // MaximumAttributeByteCount (no max)
                             // AttributeIDList
                             0x35, 0x03,  // Sequence uint8 3 bytes
                             0x09,        // uint16_t, single attribute
                             0x00, 0x05,  // BrowseGroupList
                             0x00         // Contunuation State: none
      );

  ServiceSearchAttributeResponse rsp;
  auto send_cb = [&rsp](auto cb_packet) {
    EXPECT_LE(sizeof(Header), cb_packet->size());
    PacketView<sdp::Header> packet(cb_packet.get());
    ASSERT_EQ(0x07, packet.header().pdu_id);
    uint16_t len = betoh16(packet.header().param_length);
    packet.Resize(len);
    auto status = rsp.Parse(packet.payload_data());
    EXPECT_TRUE(status);
  };

  fake_chan()->SetSendCallback(send_cb, dispatcher());
  fake_chan()->Receive(kRequestAttr);
  RunLoopUntilIdle();

  EXPECT_EQ(1u, rsp.num_attribute_lists());
  auto& attributes = rsp.attributes(0);
  auto group_attr_it = attributes.find(kBrowseGroupList);
  ASSERT_EQ(DataElement::Type::kSequence, group_attr_it->second.type());
  ASSERT_EQ(DataElement::Type::kUuid, group_attr_it->second.At(0)->type());
  EXPECT_NE(attributes.end(), group_attr_it);
  EXPECT_EQ(kPublicBrowseRootUuid, *group_attr_it->second.At(0)->Get<UUID>());
}

#undef SDP_ERROR_RSP
#undef UINT32_AS_LE_BYTES

}  // namespace
}  // namespace sdp
}  // namespace bt
