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

#include <zircon/assert.h>

#include <gtest/gtest.h>

#include "src/connectivity/bluetooth/core/bt-host/common/test_helpers.h"

namespace bt {
namespace att {
namespace {

constexpr Handle kTestRangeStart = 1;
constexpr Handle kTestRangeEnd = 10;

constexpr UUID kTestType1((uint16_t)1);
constexpr UUID kTestType2((uint16_t)2);
constexpr UUID kTestType3((uint16_t)3);

const AccessRequirements kAllowed(false, false, false);
const sm::SecurityProperties kNoSecurity(sm::SecurityLevel::kNoSecurity, 16, false);

// Values with different lengths
const auto kTestValue1 = CreateStaticByteBuffer('x', 'x');
const auto kTestValue2 = CreateStaticByteBuffer('x', 'x', 'x');

// Returns the handles of each attribute visited by advancing |iter| until the
// end.
std::vector<Handle> IterHandles(Database::Iterator* iter) {
  ZX_DEBUG_ASSERT(iter);

  std::vector<Handle> handles;
  for (; !iter->AtEnd(); iter->Advance()) {
    handles.push_back(iter->get()->handle());
  }
  return handles;
}

TEST(ATT_DatabaseTest, NewGroupingWhileEmptyError) {
  constexpr size_t kTooLarge = kTestRangeEnd - kTestRangeStart + 1;
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  EXPECT_FALSE(db->NewGrouping(kTestType1, kTooLarge, kTestValue1));
}

TEST(ATT_DatabaseTest, NewGroupingWhileEmptyFill) {
  constexpr size_t kExact = kTestRangeEnd - kTestRangeStart;

  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto* grp = db->NewGrouping(kTestType1, kExact, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(kTestType1, grp->group_type());
  EXPECT_EQ(kTestRangeStart, grp->start_handle());
  EXPECT_EQ(kTestRangeEnd, grp->end_handle());

  // Ran out of space.
  EXPECT_FALSE(db->NewGrouping(kTestType1, 0, kTestValue1));
}

// This test case performs multiple insertions and removals on the same
// database.
TEST(ATT_DatabaseTest, NewGroupingMultipleInsertions) {
  // [__________]
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);

  // Insert to empty db
  // [XXX_______] (insert X)
  auto* grp = db->NewGrouping(kTestType1, 2, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(1, grp->start_handle());
  EXPECT_EQ(3, grp->end_handle());

  // Not enough space
  grp = db->NewGrouping(kTestType1, 7, kTestValue1);
  EXPECT_FALSE(grp);

  // Insert back
  // [XXXYYYYY__] (insert Y)
  grp = db->NewGrouping(kTestType1, 4, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(4, grp->start_handle());
  EXPECT_EQ(8, grp->end_handle());

  // Not enough space
  grp = db->NewGrouping(kTestType1, 2, kTestValue1);
  EXPECT_FALSE(grp);

  // Insert back
  // [XXXYYYYYZZ] (insert Z)
  grp = db->NewGrouping(kTestType1, 1, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(9, grp->start_handle());
  EXPECT_EQ(10, grp->end_handle());

  // Out of space
  EXPECT_FALSE(db->NewGrouping(kTestType1, 0, kTestValue1));

  // Remove first grouping. It should be possible to reinsert a smaller group.
  // [___YYYYYZZ]
  EXPECT_TRUE(db->RemoveGrouping(1));

  // Not enough space
  grp = db->NewGrouping(kTestType1, 3, kTestValue1);
  EXPECT_FALSE(grp);

  // Insert front
  // [XX_YYYYYZZ] (insert X)
  grp = db->NewGrouping(kTestType1, 1, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(1, grp->start_handle());
  EXPECT_EQ(2, grp->end_handle());

  // Handle doesn't exist.
  EXPECT_FALSE(db->RemoveGrouping(3));

  // Insert in the middle
  // [XXWYYYYYZZ] (insert W)
  grp = db->NewGrouping(kTestType1, 0, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(3, grp->start_handle());
  EXPECT_EQ(3, grp->end_handle());

  // [XXW_____ZZ] (remove Y)
  EXPECT_TRUE(db->RemoveGrouping(4));

  // Insert in the middle
  // [XXWAAA__ZZ] (insert A)
  grp = db->NewGrouping(kTestType1, 2, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(4, grp->start_handle());
  EXPECT_EQ(6, grp->end_handle());

  // Insert in the middle
  // [XXWAAABBZZ] (insert B)
  grp = db->NewGrouping(kTestType1, 1, kTestValue1);
  ASSERT_TRUE(grp);
  EXPECT_EQ(7, grp->start_handle());
  EXPECT_EQ(8, grp->end_handle());

  // Out of space
  EXPECT_FALSE(db->NewGrouping(kTestType1, 0, kTestValue1));
}

TEST(ATT_DatabaseTest, RemoveWhileEmpty) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  EXPECT_FALSE(db->RemoveGrouping(kTestRangeStart));
}

TEST(ATT_DatabaseTest, FindAttributeInvalidHandle) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  EXPECT_EQ(nullptr, db->FindAttribute(kInvalidHandle));
}

TEST(ATT_DatabaseTest, FindAttributeGroupingNotFound) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);

  // Create the following layout:
  //
  // handle 0x0001: occupied
  // handle 0x0002: empty
  // handle 0x0003: occupied
  db->NewGrouping(kTestType1, 0, kTestValue1)->set_active(true);
  auto* grp = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp->set_active(true);
  db->NewGrouping(kTestType1, 0, kTestValue1)->set_active(true);
  db->RemoveGrouping(grp->start_handle());

  EXPECT_EQ(nullptr, db->FindAttribute(0xFFFF));
  EXPECT_EQ(nullptr, db->FindAttribute(0x0002));
  EXPECT_NE(nullptr, db->FindAttribute(0x0001));
  EXPECT_NE(nullptr, db->FindAttribute(0x0003));
}

TEST(ATT_DatabaseTest, FindAttributeIncompleteGrouping) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto* grp = db->NewGrouping(kTestType1, 1, kTestValue1);
  EXPECT_EQ(nullptr, db->FindAttribute(grp->start_handle()));
}

TEST(ATT_DatabaseTest, FindAttributeInactiveGrouping) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto* grp = db->NewGrouping(kTestType1, 0, kTestValue1);
  EXPECT_EQ(nullptr, db->FindAttribute(grp->start_handle()));
}

TEST(ATT_DatabaseTest, FindAttributeOnePerGrouping) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto* grp1 = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp1->set_active(true);
  auto* grp2 = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp2->set_active(true);

  EXPECT_EQ(&grp1->attributes()[0], db->FindAttribute(grp1->start_handle()));
  EXPECT_EQ(&grp2->attributes()[0], db->FindAttribute(grp2->start_handle()));
}

TEST(ATT_DatabaseTest, FindAttributeIndexIntoGrouping) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);

  auto* grp = db->NewGrouping(kTestType1, 1, kTestValue1);
  auto* attr = grp->AddAttribute(kTestType2, AccessRequirements(), AccessRequirements());
  grp->set_active(true);

  EXPECT_EQ(attr, db->FindAttribute(grp->end_handle()));
}

TEST(ATT_DatabaseTest, IteratorEmpty) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto iter = db->GetIterator(kTestRangeStart, kTestRangeEnd);
  EXPECT_TRUE(iter.AtEnd());
  EXPECT_FALSE(iter.get());

  // Advance should have no effect.
  iter.Advance();
  EXPECT_TRUE(iter.AtEnd());
}

TEST(ATT_DatabaseTest, IteratorGroupOnlySingleInactive) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  db->NewGrouping(kTestType1, 0, kTestValue1);

  // |grp| is not active
  auto iter = db->GetIterator(kTestRangeStart, kTestRangeEnd, nullptr, true /* groups_only */);
  EXPECT_TRUE(iter.AtEnd());
  EXPECT_FALSE(iter.get());
}

TEST(ATT_DatabaseTest, IteratorGroupOnlySingle) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto grp = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp->set_active(true);

  // Not within range.
  auto iter =
      db->GetIterator(grp->start_handle() + 1, kTestRangeEnd, nullptr, true /* groups_only */);
  EXPECT_TRUE(iter.AtEnd());
  EXPECT_FALSE(iter.get());

  iter = db->GetIterator(kTestRangeStart, kTestRangeEnd, nullptr, true /* groups_only */);
  EXPECT_FALSE(iter.AtEnd());

  auto handles = IterHandles(&iter);
  ASSERT_EQ(1u, handles.size());
  EXPECT_EQ(grp->start_handle(), handles[0]);
}

TEST(ATT_DatabaseTest, IteratorGroupOnlyMultiple) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto grp1 = db->NewGrouping(kTestType1, 0, kTestValue1);
  auto grp2 = db->NewGrouping(kTestType1, 0, kTestValue1);
  auto grp3 = db->NewGrouping(kTestType1, 0, kTestValue1);
  auto grp4 = db->NewGrouping(kTestType1, 0, kTestValue1);

  // Leave |grp2| as inactive.
  grp1->set_active(true);
  grp3->set_active(true);
  grp4->set_active(true);

  auto iter = db->GetIterator(kTestRangeStart, kTestRangeEnd, nullptr, true /* groups_only */);
  EXPECT_FALSE(iter.AtEnd());

  // |grp2| should be omitted.
  auto handles = IterHandles(&iter);
  ASSERT_EQ(3u, handles.size());
  EXPECT_EQ(grp1->start_handle(), handles[0]);
  EXPECT_EQ(grp3->start_handle(), handles[1]);
  EXPECT_EQ(grp4->start_handle(), handles[2]);

  grp2->set_active(true);

  // Pick a narrow range that excludes |grp1| and |grp4|.
  iter = db->GetIterator(grp2->start_handle(), grp3->end_handle(), nullptr, true /* groups_only */);
  handles = IterHandles(&iter);
  ASSERT_EQ(2u, handles.size());
  EXPECT_EQ(grp2->start_handle(), handles[0]);
  EXPECT_EQ(grp3->start_handle(), handles[1]);
}

TEST(ATT_DatabaseTest, IteratorGroupOnlySingleWithFilter) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);

  auto grp = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp->set_active(true);

  // No match.
  auto iter = db->GetIterator(kTestRangeStart, kTestRangeEnd, &kTestType2, true /* groups_only */);
  EXPECT_TRUE(iter.AtEnd());

  iter = db->GetIterator(kTestRangeStart, kTestRangeEnd, &kTestType1, true /* groups_only */);
  EXPECT_FALSE(iter.AtEnd());

  auto handles = IterHandles(&iter);
  ASSERT_EQ(1u, handles.size());
  EXPECT_EQ(grp->start_handle(), handles[0]);
}

TEST(ATT_DatabaseTest, IteratorGroupOnlyManyWithFilter) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);

  auto grp1 = db->NewGrouping(kTestType1, 1, kTestValue1);  // match
  grp1->AddAttribute(kTestType1);                           // match but skipped - not group decl.
  grp1->set_active(true);

  // Matching but inactive.
  db->NewGrouping(kTestType1, 0, kTestValue1);

  auto grp2 = db->NewGrouping(kTestType2, 0, kTestValue1);
  grp2->set_active(true);
  auto grp3 = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp3->set_active(true);
  auto grp4 = db->NewGrouping(kTestType2, 0, kTestValue1);
  grp4->set_active(true);
  auto grp5 = db->NewGrouping(kTestType2, 0, kTestValue1);
  grp5->set_active(true);
  auto grp6 = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp6->set_active(true);

  // Filter by |kTestType1|
  auto iter = db->GetIterator(kTestRangeStart, kTestRangeEnd, &kTestType1, true /* groups_only */);
  EXPECT_FALSE(iter.AtEnd());

  auto handles = IterHandles(&iter);
  ASSERT_EQ(3u, handles.size());
  EXPECT_EQ(grp1->start_handle(), handles[0]);
  EXPECT_EQ(grp3->start_handle(), handles[1]);
  EXPECT_EQ(grp6->start_handle(), handles[2]);

  // Filter by |kTestType2|
  iter = db->GetIterator(kTestRangeStart, kTestRangeEnd, &kTestType2, true /* groups_only */);
  EXPECT_FALSE(iter.AtEnd());

  handles = IterHandles(&iter);
  ASSERT_EQ(3u, handles.size());
  EXPECT_EQ(grp2->start_handle(), handles[0]);
  EXPECT_EQ(grp4->start_handle(), handles[1]);
  EXPECT_EQ(grp5->start_handle(), handles[2]);

  // Search narrower range.
  iter =
      db->GetIterator(grp1->end_handle(), grp5->end_handle(), &kTestType1, true /* groups_only */);
  EXPECT_FALSE(iter.AtEnd());

  handles = IterHandles(&iter);
  ASSERT_EQ(1u, handles.size());
  EXPECT_EQ(grp3->start_handle(), handles[0]);
}

TEST(ATT_DatabaseTest, IteratorSingleInactive) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto grp = db->NewGrouping(kTestType1, 1, kTestValue1);

  auto iter = db->GetIterator(kTestRangeStart, kTestRangeEnd);
  EXPECT_TRUE(iter.AtEnd());
  EXPECT_FALSE(iter.get());

  // Complete but still inactive.
  grp->AddAttribute(kTestType1);
  iter = db->GetIterator(kTestRangeStart, kTestRangeEnd);
  EXPECT_TRUE(iter.AtEnd());
  EXPECT_FALSE(iter.get());
}

TEST(ATT_DatabaseTest, IteratorSingle) {
  auto db = Database::Create(kTestRangeStart, kTestRangeEnd);
  auto grp = db->NewGrouping(kTestType1, 0, kTestValue1);
  grp->set_active(true);

  // Not within range.
  auto iter = db->GetIterator(grp->start_handle() + 1, kTestRangeEnd);
  EXPECT_TRUE(iter.AtEnd());
  EXPECT_FALSE(iter.get());

  iter = db->GetIterator(kTestRangeStart, kTestRangeEnd);
  EXPECT_FALSE(iter.AtEnd());

  auto handles = IterHandles(&iter);
  ASSERT_EQ(1u, handles.size());
  EXPECT_EQ(grp->start_handle(), handles[0]);
}

class ATT_DatabaseIteratorManyTest : public ::testing::Test {
 public:
  ATT_DatabaseIteratorManyTest() = default;
  ~ATT_DatabaseIteratorManyTest() override = default;

 protected:
  static constexpr size_t kActiveAttrCount = 8;

  void SetUp() override {
    db_ = Database::Create(kTestRangeStart, kTestRangeEnd);

    auto grp1 = db()->NewGrouping(kTestType1, 3, kTestValue1);  // 1
    grp1->AddAttribute(kTestType2);                             // 2
    grp1->AddAttribute(kTestType2);                             // 3
    grp1->AddAttribute(kTestType1);                             // 4
    grp1->set_active(true);

    auto grp2 = db()->NewGrouping(kTestType2, 2, kTestValue1);  // 5
    grp2->AddAttribute(kTestType1);                             // 6
    grp2->AddAttribute(kTestType2);                             // 7
    grp2->set_active(true);

    auto grp3 = db()->NewGrouping(kTestType1, 1, kTestValue1);  // 8 (inactive)
    grp3->AddAttribute(kTestType2);                             // 9 (inactive)

    auto grp4 = db()->NewGrouping(kTestType1, 0, kTestValue1);  // 10
    grp4->set_active(true);
  }

  Database* db() const { return db_.get(); }

 private:
  fxl::RefPtr<Database> db_;

  DISALLOW_COPY_ASSIGN_AND_MOVE(ATT_DatabaseIteratorManyTest);
};

// static
const size_t ATT_DatabaseIteratorManyTest::kActiveAttrCount;

TEST_F(ATT_DatabaseIteratorManyTest, NoFilter) {
  auto iter = db()->GetIterator(kTestRangeStart, kTestRangeEnd);
  EXPECT_FALSE(iter.AtEnd());

  // Should cover all but the inactive attribute.
  auto handles = IterHandles(&iter);

  // All active attribute handles.
  const std::array<Handle, kActiveAttrCount> kExpected = {1, 2, 3, 4, 5, 6, 7, 10};
  ASSERT_EQ(kExpected.size(), handles.size());

  for (size_t i = 0; i < handles.size(); i++) {
    EXPECT_EQ(kExpected[i], handles[i]);
  }
}

TEST_F(ATT_DatabaseIteratorManyTest, FilterTestType1) {
  // Filter by |kTestType1|.
  auto iter = db()->GetIterator(kTestRangeStart, kTestRangeEnd, &kTestType1);
  EXPECT_FALSE(iter.AtEnd());

  auto handles = IterHandles(&iter);

  // Handles of attributes with type |kTestType1|.
  const std::array<Handle, 4u> kExpected = {1, 4, 6, 10};
  ASSERT_EQ(kExpected.size(), handles.size());

  for (size_t i = 0; i < handles.size(); i++) {
    EXPECT_EQ(kExpected[i], handles[i]);
  }
}

TEST_F(ATT_DatabaseIteratorManyTest, FilterTestType2) {
  // Filter by |kTestType2|.
  auto iter = db()->GetIterator(kTestRangeStart, kTestRangeEnd, &kTestType2);
  EXPECT_FALSE(iter.AtEnd());

  auto handles = IterHandles(&iter);

  // Handles of attributes with type |kTestType2|.
  const std::array<Handle, 4u> kExpected = {2, 3, 5, 7};
  ASSERT_EQ(kExpected.size(), handles.size());

  for (size_t i = 0; i < handles.size(); i++) {
    EXPECT_EQ(kExpected[i], handles[i]);
  }
}

TEST_F(ATT_DatabaseIteratorManyTest, FilterTestType3) {
  // Filter by |kTestType3|.
  auto iter = db()->GetIterator(kTestRangeStart, kTestRangeEnd, &kTestType3);
  EXPECT_TRUE(iter.AtEnd());
}

TEST_F(ATT_DatabaseIteratorManyTest, UnaryRange) {
  // Test ranges with a single attribute. Test group begin, middle, and end
  // cases.
  constexpr Handle kBegin = 5;
  constexpr Handle kMiddle = 6;
  constexpr Handle kEnd = 7;

  auto iter = db()->GetIterator(kBegin, kBegin);
  EXPECT_FALSE(iter.AtEnd());
  auto handles = IterHandles(&iter);
  ASSERT_EQ(1u, handles.size());
  EXPECT_EQ(kBegin, handles[0]);

  iter = db()->GetIterator(kMiddle, kMiddle);
  EXPECT_FALSE(iter.AtEnd());
  handles = IterHandles(&iter);
  ASSERT_EQ(1u, handles.size());
  EXPECT_EQ(kMiddle, handles[0]);

  iter = db()->GetIterator(kEnd, kEnd);
  EXPECT_FALSE(iter.AtEnd());
  handles = IterHandles(&iter);
  ASSERT_EQ(1u, handles.size());
  EXPECT_EQ(kEnd, handles[0]);
}

TEST_F(ATT_DatabaseIteratorManyTest, Range) {
  auto iter = db()->GetIterator(4, 6);
  EXPECT_FALSE(iter.AtEnd());

  auto handles = IterHandles(&iter);

  // All active attribute handles.
  const std::array<Handle, 3> kExpected = {4, 5, 6};
  ASSERT_EQ(kExpected.size(), handles.size());

  for (size_t i = 0; i < handles.size(); i++) {
    EXPECT_EQ(kExpected[i], handles[i]);
  }
}

class ATT_DatabaseExecuteWriteQueueTest : public ::testing::Test {
 public:
  ATT_DatabaseExecuteWriteQueueTest() = default;
  ~ATT_DatabaseExecuteWriteQueueTest() = default;

 protected:
  struct PendingWrite {
    PeerId peer_id;
    Handle handle;
    uint16_t offset;
    DynamicByteBuffer value;
    Attribute::WriteResultCallback result_callback;
  };

  void SetUp() override { db_ = Database::Create(kTestRangeStart, kTestRangeEnd); }

  void ExecuteWriteQueue(PeerId peer_id, PrepareWriteQueue wq,
                         const sm::SecurityProperties& security = kNoSecurity) {
    db_->ExecuteWriteQueue(peer_id, std::move(wq), security, [this](Handle h, ErrorCode e) {
      callback_count_++;
      ecode_ = e;
      handle_in_error_ = h;
    });
  }

  // Sets up an attribute grouping with 4 attributes.
  void SetUpAttributes() {
    auto* grp = db()->NewGrouping(kTestType1, 3, kTestValue1);  // handle: 1
    group_decl_handle_ = grp->start_handle();

    auto* attr = grp->AddAttribute(kTestType2, kAllowed, kAllowed);  // handle: 2
    attr->set_write_handler(
        fit::bind_member(this, &ATT_DatabaseExecuteWriteQueueTest::WriteHandler));
    test_handle1_ = attr->handle();

    attr = grp->AddAttribute(kTestType2, kAllowed, kAllowed);  // handle: 3
    attr->set_write_handler(
        fit::bind_member(this, &ATT_DatabaseExecuteWriteQueueTest::WriteHandler));
    test_handle2_ = attr->handle();

    attr = grp->AddAttribute(kTestType2, kAllowed, kAllowed);  // handle: 4
    attr->set_write_handler(
        fit::bind_member(this, &ATT_DatabaseExecuteWriteQueueTest::WriteHandler));
    test_handle3_ = attr->handle();

    grp->set_active(true);
  }

  void ResolveNextPendingWrite(ErrorCode ecode) {
    ASSERT_FALSE(pending_writes_.empty());
    auto pw = std::move(pending_writes_.front());
    pending_writes_.pop();

    pw.result_callback(ecode);
  }

  ErrorCode ecode() const { return ecode_; }
  Handle handle_in_error() const { return handle_in_error_; }
  int callback_count() const { return callback_count_; }

  Handle group_decl_handle() const { return group_decl_handle_; }
  Handle test_handle1() const { return test_handle1_; }
  Handle test_handle2() const { return test_handle2_; }
  Handle test_handle3() const { return test_handle3_; }

  const std::queue<PendingWrite>& pending_writes() const { return pending_writes_; }

  Database* db() { return db_.get(); }

 private:
  void WriteHandler(PeerId peer_id, Handle handle, uint16_t offset, const ByteBuffer& value,
                    Attribute::WriteResultCallback result_callback) {
    PendingWrite pw;
    pw.peer_id = peer_id;
    pw.handle = handle;
    pw.offset = offset;
    pw.value = DynamicByteBuffer(value);
    pw.result_callback = std::move(result_callback);

    pending_writes_.push(std::move(pw));
  }

  ErrorCode ecode_ = ErrorCode::kNoError;
  Handle handle_in_error_ = kInvalidHandle;
  int callback_count_ = 0;
  fxl::RefPtr<Database> db_;
  std::queue<PendingWrite> pending_writes_;

  // Handles of the test attributes.
  Handle group_decl_handle_ = kInvalidHandle;
  Handle test_handle1_ = kInvalidHandle;
  Handle test_handle2_ = kInvalidHandle;
  Handle test_handle3_ = kInvalidHandle;

  DISALLOW_COPY_ASSIGN_AND_MOVE(ATT_DatabaseExecuteWriteQueueTest);
};

constexpr PeerId kPeerId(1);

TEST_F(ATT_DatabaseExecuteWriteQueueTest, EmptyQueueSucceedsImmediately) {
  ExecuteWriteQueue(kPeerId, {});
  EXPECT_EQ(1, callback_count());
  EXPECT_EQ(ErrorCode::kNoError, ecode());
  EXPECT_EQ(kInvalidHandle, handle_in_error());
}

TEST_F(ATT_DatabaseExecuteWriteQueueTest, InvalidHandle) {
  constexpr Handle kHandle = 1;
  PrepareWriteQueue wq;
  wq.push(QueuedWrite(kHandle, 0, BufferView()));

  ExecuteWriteQueue(kPeerId, std::move(wq));
  EXPECT_EQ(1, callback_count());
  EXPECT_EQ(ErrorCode::kInvalidHandle, ecode());
  EXPECT_EQ(kHandle, handle_in_error());
}

TEST_F(ATT_DatabaseExecuteWriteQueueTest, ValueLength) {
  auto* grp = db()->NewGrouping(kTestType1, 1, kTestValue1);
  auto* attr = grp->AddAttribute(kTestType2);
  grp->set_active(true);

  PrepareWriteQueue wq;
  wq.push(QueuedWrite(attr->handle(), 0, DynamicByteBuffer(kMaxAttributeValueLength + 1)));

  ExecuteWriteQueue(kPeerId, std::move(wq));
  EXPECT_EQ(1, callback_count());
  EXPECT_EQ(ErrorCode::kInvalidAttributeValueLength, ecode());
  EXPECT_EQ(attr->handle(), handle_in_error());
}

TEST_F(ATT_DatabaseExecuteWriteQueueTest, WritingStaticValueNotPermitted) {
  auto* grp = db()->NewGrouping(kTestType1, 1, kTestValue1);
  auto* attr = grp->AddAttribute(kTestType2);  // read/write not permitted
  grp->set_active(true);

  PrepareWriteQueue wq;
  wq.push(QueuedWrite(attr->handle(), 0, kTestValue1));

  ExecuteWriteQueue(kPeerId, std::move(wq));
  EXPECT_EQ(1, callback_count());
  EXPECT_EQ(ErrorCode::kWriteNotPermitted, ecode());
  EXPECT_EQ(attr->handle(), handle_in_error());
}

TEST_F(ATT_DatabaseExecuteWriteQueueTest, SecurityChecks) {
  auto* grp = db()->NewGrouping(kTestType1, 1, kTestValue1);
  auto* attr =
      grp->AddAttribute(kTestType2, att::AccessRequirements(),
                        att::AccessRequirements(true, false, false));  // write requires encryption
  grp->set_active(true);

  PrepareWriteQueue wq;
  wq.push(QueuedWrite(attr->handle(), 0, kTestValue1));

  ExecuteWriteQueue(kPeerId, std::move(wq), kNoSecurity);
  EXPECT_EQ(1, callback_count());
  EXPECT_EQ(ErrorCode::kInsufficientAuthentication, ecode());
  EXPECT_EQ(attr->handle(), handle_in_error());

  // Request should succeed with an encrypted link.
  ExecuteWriteQueue(kPeerId, std::move(wq),
                    sm::SecurityProperties(sm::SecurityLevel::kEncrypted, 16, false));
  EXPECT_EQ(2, callback_count());
  EXPECT_EQ(ErrorCode::kNoError, ecode());
}

// If an error is caught before delivering the request to the delegate then we
// expect subsequent entries to not be delivered.
TEST_F(ATT_DatabaseExecuteWriteQueueTest, UndelegatedWriteErrorAborts) {
  SetUpAttributes();
  PrepareWriteQueue wq;

  // Queue a request to one of the delegated handles. This won't generate a
  // result until we explicitly send a reply via ResolveNextPendingWrite().
  wq.push(QueuedWrite(test_handle1(), 0, kTestValue1));

  // Queue a write to the group declaration handle. This should get rejected
  // right away since it's not writable. Since the database catches this error
  // internally, we expect the following queued writes to get aborted.
  wq.push(QueuedWrite(group_decl_handle(), 0, kTestValue1));

  // Queue more writes.
  wq.push(QueuedWrite(test_handle2(), 1, kTestValue2));
  wq.push(QueuedWrite(test_handle3(), 2, kTestValue1));
  wq.push(QueuedWrite(test_handle1(), 3, kTestValue2));

  ExecuteWriteQueue(kPeerId, std::move(wq));

  // The database should have generated an error response.
  EXPECT_EQ(1, callback_count());
  EXPECT_EQ(ErrorCode::kWriteNotPermitted, ecode());
  EXPECT_EQ(group_decl_handle(), handle_in_error());

  // Only the first write should have been delivered.
  ASSERT_EQ(1u, pending_writes().size());
  EXPECT_EQ(test_handle1(), pending_writes().front().handle);
  EXPECT_EQ(0, pending_writes().front().offset);
  EXPECT_TRUE(ContainersEqual(kTestValue1, pending_writes().front().value));

  // Resolving the request should have no effect.
  ResolveNextPendingWrite(ErrorCode::kUnlikelyError);
  EXPECT_EQ(1, callback_count());  // still 1
}

TEST_F(ATT_DatabaseExecuteWriteQueueTest, ErrorInMultipleQueuedWrites) {
  SetUpAttributes();
  PrepareWriteQueue wq;

  // Queue writes to the writable handles in arbitrary order. We expect all of
  // them to be delivered to the delegate.
  wq.push(QueuedWrite(test_handle1(), 0, kTestValue1));
  wq.push(QueuedWrite(test_handle2(), 1, kTestValue2));
  wq.push(QueuedWrite(test_handle3(), 2, kTestValue1));
  wq.push(QueuedWrite(test_handle1(), 3, kTestValue2));

  ExecuteWriteQueue(kPeerId, std::move(wq));

  // The execute write request should be pending.
  EXPECT_EQ(0, callback_count());

  // All 4 requests should have been delivered.
  ASSERT_EQ(4u, pending_writes().size());

  // Resolve the first request with success. The execute write request should
  // remain pending.
  {
    const auto& next = pending_writes().front();
    EXPECT_EQ(kPeerId, next.peer_id);
    EXPECT_EQ(test_handle1(), next.handle);
    EXPECT_EQ(0, next.offset);
    EXPECT_TRUE(ContainersEqual(kTestValue1, next.value));

    ResolveNextPendingWrite(ErrorCode::kNoError);
    EXPECT_EQ(0, callback_count());
  }

  // Resolve the second request with an error.
  {
    const auto& next = pending_writes().front();
    EXPECT_EQ(kPeerId, next.peer_id);
    EXPECT_EQ(test_handle2(), next.handle);
    EXPECT_EQ(1, next.offset);
    EXPECT_TRUE(ContainersEqual(kTestValue2, next.value));

    ResolveNextPendingWrite(ErrorCode::kUnlikelyError);
    EXPECT_EQ(1, callback_count());
    EXPECT_EQ(ErrorCode::kUnlikelyError, ecode());
    EXPECT_EQ(test_handle2(), handle_in_error());
  }

  // Resolving the remaining writes should have no effect.
  ResolveNextPendingWrite(ErrorCode::kNoError);
  ResolveNextPendingWrite(ErrorCode::kUnlikelyError);
  EXPECT_EQ(1, callback_count());
}

TEST_F(ATT_DatabaseExecuteWriteQueueTest, MultipleQueuedWritesSucceed) {
  SetUpAttributes();
  PrepareWriteQueue wq;

  // Queue writes to the writable handles in arbitrary order. We expect all of
  // them to be delivered to the delegate.
  wq.push(QueuedWrite(test_handle1(), 0, kTestValue1));
  wq.push(QueuedWrite(test_handle2(), 1, kTestValue2));
  wq.push(QueuedWrite(test_handle3(), 2, kTestValue1));
  wq.push(QueuedWrite(test_handle1(), 3, kTestValue2));

  ExecuteWriteQueue(kPeerId, std::move(wq));

  // The execute write request should be pending.
  EXPECT_EQ(0, callback_count());

  // All 4 requests should have been delivered.
  ASSERT_EQ(4u, pending_writes().size());

  // Resolve all requests with success.
  {
    const auto& next = pending_writes().front();
    EXPECT_EQ(kPeerId, next.peer_id);
    EXPECT_EQ(test_handle1(), next.handle);
    EXPECT_EQ(0, next.offset);
    EXPECT_TRUE(ContainersEqual(kTestValue1, next.value));

    ResolveNextPendingWrite(ErrorCode::kNoError);
    EXPECT_EQ(0, callback_count());
  }
  {
    const auto& next = pending_writes().front();
    EXPECT_EQ(kPeerId, next.peer_id);
    EXPECT_EQ(test_handle2(), next.handle);
    EXPECT_EQ(1, next.offset);
    EXPECT_TRUE(ContainersEqual(kTestValue2, next.value));

    ResolveNextPendingWrite(ErrorCode::kNoError);
    EXPECT_EQ(0, callback_count());
  }
  {
    const auto& next = pending_writes().front();
    EXPECT_EQ(kPeerId, next.peer_id);
    EXPECT_EQ(test_handle3(), next.handle);
    EXPECT_EQ(2, next.offset);
    EXPECT_TRUE(ContainersEqual(kTestValue1, next.value));

    ResolveNextPendingWrite(ErrorCode::kNoError);
    EXPECT_EQ(0, callback_count());
  }

  // Resolving the last request should complete the execute write request.
  {
    const auto& next = pending_writes().front();
    EXPECT_EQ(kPeerId, next.peer_id);
    EXPECT_EQ(test_handle1(), next.handle);
    EXPECT_EQ(3, next.offset);
    EXPECT_TRUE(ContainersEqual(kTestValue2, next.value));

    ResolveNextPendingWrite(ErrorCode::kNoError);
    EXPECT_EQ(1, callback_count());
    EXPECT_EQ(ErrorCode::kNoError, ecode());
  }
}

}  // namespace
}  // namespace att
}  // namespace bt
