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

#include <forward_list>

#include <gtest/gtest.h>

#include "acl_data_packet.h"
#include "control_packets.h"

namespace bt {
namespace hci {
namespace slab_allocators {
namespace {

constexpr OpCode kTestOpCode = 0xFFFF;

TEST(HCI_SlabAllocatorsTest, CommandPacket) {
  auto packet = CommandPacket::New(kTestOpCode, 5);
  EXPECT_TRUE(packet);
  EXPECT_EQ(5u + sizeof(CommandHeader), packet->view().size());

  packet = CommandPacket::New(kTestOpCode, kSmallControlPayloadSize);
  EXPECT_TRUE(packet);
  EXPECT_GE(packet->view().size(), kSmallControlPacketSize);

  packet = CommandPacket::New(kTestOpCode, kSmallControlPayloadSize + 1);
  EXPECT_TRUE(packet);
  EXPECT_EQ(kSmallControlPacketSize + 1, packet->view().size());
}

TEST(HCI_SlabAllocatorsTest, CommandPacketFallBack) {
  size_t num_packets = 0;
  LinkedList<Packet<CommandHeader>> packets;

  // Allocate a lot of small packets. We should be able to allocate two
  // allocators' worth of packets until we fail.
  while (auto packet = CommandPacket::New(kTestOpCode, 5)) {
    packets.push_front(std::move(packet));
    num_packets++;
  }

  EXPECT_EQ(kMaxNumSlabs * kNumSmallControlPackets + kMaxNumSlabs * kNumLargeControlPackets,
            num_packets);
}

TEST(HCI_SlabAllocatorsTest, ACLDataPacket) {
  auto packet = ACLDataPacket::New(5);
  EXPECT_TRUE(packet);
  EXPECT_EQ(packet->view().size(), 5u + sizeof(ACLDataHeader));

  packet = ACLDataPacket::New(kSmallACLDataPayloadSize);
  EXPECT_TRUE(packet);
  EXPECT_EQ(kSmallACLDataPacketSize, packet->view().size());

  packet = ACLDataPacket::New(kSmallACLDataPayloadSize + 1);
  EXPECT_TRUE(packet);
  EXPECT_EQ(kSmallACLDataPacketSize + 1, packet->view().size());

  packet = ACLDataPacket::New(kMediumACLDataPayloadSize + 1);
  EXPECT_EQ(kMediumACLDataPacketSize + 1, packet->view().size());
}

TEST(HCI_SlabAllocatorsTest, ACLDataPacketFallBack) {
  // Maximum number of packets we can expect to obtain from all the slab allocators.
  const size_t kMaxSlabPackets = kMaxNumSlabs * kNumSmallACLDataPackets +
                                 kMaxNumSlabs * kNumMediumACLDataPackets +
                                 kMaxNumSlabs * kNumLargeACLDataPackets;
  const size_t kPayloadSize = 5;
  LinkedList<Packet<ACLDataHeader>> packets;

  for (size_t num_packets = 0; num_packets < kMaxSlabPackets; num_packets++) {
    auto packet = ACLDataPacket::New(kPayloadSize);
    EXPECT_TRUE(packet);
    packets.push_front(std::move(packet));
  }

  // ACL allocator can fall back on system allocator after slabs are exhausted.
  auto packet = ACLDataPacket::New(kPayloadSize);
  ASSERT_TRUE(packet);

  // Fallback-allocated packet should still function as expected.
  EXPECT_EQ(sizeof(ACLDataHeader) + kPayloadSize, packet->view().size());

  // Write over the whole allocation (errors to be caught by sanitizer instrumentation).
  packet->mutable_view()->mutable_data().Fill('m');
}

}  // namespace
}  // namespace slab_allocators
}  // namespace hci
}  // namespace bt
