/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

#include <cluster/redis_slot.h>
#include <fmt/format.h>
#include <storage/iterator.h>
#include <types/redis_bitmap.h>
#include <types/redis_bloom_chain.h>
#include <types/redis_json.h>
#include <types/redis_list.h>
#include <types/redis_set.h>
#include <types/redis_sortedint.h>
#include <types/redis_stream.h>
#include <types/redis_zset.h>

#include "test_base.h"
#include "types/redis_string.h"

class DBIteratorTest : public TestBase {
 protected:
  explicit DBIteratorTest() = default;
  ~DBIteratorTest() override = default;

  void SetUp() override {
    {  // string
      redis::String string(storage_.get(), "test_ns0");
      string.Set(*ctx_, "a", "1");
      string.Set(*ctx_, "b", "2");
      string.Set(*ctx_, "c", "3");
      // Make sure the key "c" is expired
      auto s = string.Expire(*ctx_, "c", 1);
      ASSERT_TRUE(s.ok());
      string.Set(*ctx_, "d", "4");
    }

    {  // hash
      uint64_t ret = 0;
      redis::Hash hash(storage_.get(), "test_ns1");
      hash.MSet(*ctx_, "hash-1", {{"f0", "v0"}, {"f1", "v1"}, {"f2", "v2"}, {"f3", "v3"}}, false, &ret);
    }

    {  // set
      uint64_t ret = 0;
      redis::Set set(storage_.get(), "test_ns2");
      set.Add(*ctx_, "set-1", {"e0", "e1", "e2"}, &ret);
    }

    {  // sorted set
      uint64_t ret = 0;
      redis::ZSet zset(storage_.get(), "test_ns3");
      auto mscores = std::vector<MemberScore>{{"z0", 0}, {"z1", 1}, {"z2", 2}};
      zset.Add(*ctx_, "zset-1", ZAddFlags(), &mscores, &ret);
    }

    {  // list
      uint64_t ret = 0;
      redis::List list(storage_.get(), "test_ns4");
      list.Push(*ctx_, "list-1", {"l0", "l1", "l2"}, false, &ret);
    }

    {  // stream
      redis::Stream stream(storage_.get(), "test_ns5");
      redis::StreamEntryID ret;
      redis::StreamAddOptions options;
      options.next_id_strategy = std::make_unique<redis::AutoGeneratedEntryID>();
      stream.Add(*ctx_, "stream-1", options, {"x0"}, &ret);
      stream.Add(*ctx_, "stream-1", options, {"x1"}, &ret);
      stream.Add(*ctx_, "stream-1", options, {"x2"}, &ret);
      // TODO(@git-hulk): add stream group after it's finished
    }

    {  // bitmap
      redis::Bitmap bitmap(storage_.get(), "test_ns6");
      bool ret = false;
      bitmap.SetBit(*ctx_, "bitmap-1", 0, true, &ret);
      bitmap.SetBit(*ctx_, "bitmap-1", 8 * 1024, true, &ret);
      bitmap.SetBit(*ctx_, "bitmap-1", 2 * 8 * 1024, true, &ret);
    }

    {  // json
      redis::Json json(storage_.get(), "test_ns7");
      json.Set(*ctx_, "json-1", "$", "{\"a\": 1, \"b\": 2}");
      json.Set(*ctx_, "json-2", "$", "{\"a\": 1, \"b\": 2}");
      json.Set(*ctx_, "json-3", "$", "{\"a\": 1, \"b\": 2}");
      json.Set(*ctx_, "json-4", "$", "{\"a\": 1, \"b\": 2}");
      auto s = json.Expire(*ctx_, "json-4", 1);
      ASSERT_TRUE(s.ok());
    }

    {
      // sorted integer
      redis::Sortedint sortedint(storage_.get(), "test_ns8");
      uint64_t ret = 0;
      sortedint.Add(*ctx_, "sortedint-1", {1, 2, 3}, &ret);
    }
  }
};

TEST_F(DBIteratorTest, AllKeys) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());
  std::vector<std::string> live_keys = {"a",        "b",        "d",      "hash-1", "set-1",  "zset-1",     "list-1",
                                        "stream-1", "bitmap-1", "json-1", "json-2", "json-3", "sortedint-1"};
  std::reverse(live_keys.begin(), live_keys.end());
  for (iter.Seek(); iter.Valid(); iter.Next()) {
    ASSERT_TRUE(!live_keys.empty());
    auto [_, user_key] = iter.UserKey();
    ASSERT_EQ(live_keys.back(), user_key.ToString());
    live_keys.pop_back();
  }
  ASSERT_TRUE(live_keys.empty());
}

TEST_F(DBIteratorTest, BasicString) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());

  std::vector<std::string> expected_keys = {"a", "b", "d"};
  std::reverse(expected_keys.begin(), expected_keys.end());
  auto prefix = ComposeNamespaceKey("test_ns0", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    if (expected_keys.empty()) {
      FAIL() << "Unexpected key: " << iter.Key().ToString();
    }
    ASSERT_EQ(kRedisString, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns0", ns.ToString());
    ASSERT_EQ(expected_keys.back(), key.ToString());
    expected_keys.pop_back();
    // Make sure there is no subkey iterator
    ASSERT_TRUE(!iter.GetSubKeyIterator());
  }
  // Make sure all keys are iterated except the expired one: "c"
  ASSERT_TRUE(expected_keys.empty());
}

TEST_F(DBIteratorTest, BasicHash) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());
  auto prefix = ComposeNamespaceKey("test_ns1", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    ASSERT_EQ(kRedisHash, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns1", ns.ToString());

    auto subkey_iter = iter.GetSubKeyIterator();
    ASSERT_TRUE(subkey_iter);
    std::vector<std::string> expected_keys = {"f0", "f1", "f2", "f3"};
    std::reverse(expected_keys.begin(), expected_keys.end());
    for (subkey_iter->Seek(); subkey_iter->Valid(); subkey_iter->Next()) {
      if (expected_keys.empty()) {
        FAIL() << "Unexpected key: " << subkey_iter->UserKey().ToString();
      }
      ASSERT_EQ(expected_keys.back(), subkey_iter->UserKey().ToString());
      expected_keys.pop_back();
    }
    ASSERT_TRUE(expected_keys.empty());
  }
}

TEST_F(DBIteratorTest, BasicSet) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());
  auto prefix = ComposeNamespaceKey("test_ns2", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    ASSERT_EQ(kRedisSet, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns2", ns.ToString());

    auto subkey_iter = iter.GetSubKeyIterator();
    ASSERT_TRUE(subkey_iter);
    std::vector<std::string> expected_keys = {"e0", "e1", "e2"};
    std::reverse(expected_keys.begin(), expected_keys.end());
    for (subkey_iter->Seek(); subkey_iter->Valid(); subkey_iter->Next()) {
      if (expected_keys.empty()) {
        FAIL() << "Unexpected key: " << subkey_iter->UserKey().ToString();
      }
      ASSERT_EQ(expected_keys.back(), subkey_iter->UserKey().ToString());
      expected_keys.pop_back();
    }
    ASSERT_TRUE(expected_keys.empty());
  }
}

TEST_F(DBIteratorTest, BasicZSet) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());
  auto prefix = ComposeNamespaceKey("test_ns3", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    ASSERT_EQ(kRedisZSet, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns3", ns.ToString());

    auto subkey_iter = iter.GetSubKeyIterator();
    ASSERT_TRUE(subkey_iter);
    std::vector<std::string> expected_members = {"z0", "z1", "z2"};
    std::reverse(expected_members.begin(), expected_members.end());
    for (subkey_iter->Seek(); subkey_iter->Valid(); subkey_iter->Next()) {
      if (expected_members.empty()) {
        FAIL() << "Unexpected key: " << subkey_iter->UserKey().ToString();
      }
      ASSERT_EQ(expected_members.back(), subkey_iter->UserKey().ToString());
      expected_members.pop_back();
    }
    ASSERT_TRUE(expected_members.empty());
  }
}

TEST_F(DBIteratorTest, BasicList) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());
  auto prefix = ComposeNamespaceKey("test_ns4", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    ASSERT_EQ(kRedisList, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns4", ns.ToString());

    auto subkey_iter = iter.GetSubKeyIterator();
    ASSERT_TRUE(subkey_iter);
    std::vector<std::string> expected_values = {"l0", "l1", "l2"};
    std::reverse(expected_values.begin(), expected_values.end());
    for (subkey_iter->Seek(); subkey_iter->Valid(); subkey_iter->Next()) {
      if (expected_values.empty()) {
        FAIL() << "Unexpected value: " << subkey_iter->Value().ToString();
      }
      ASSERT_EQ(expected_values.back(), subkey_iter->Value().ToString());
      expected_values.pop_back();
    }
    ASSERT_TRUE(expected_values.empty());
  }
}

TEST_F(DBIteratorTest, BasicStream) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());
  auto prefix = ComposeNamespaceKey("test_ns5", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    ASSERT_EQ(kRedisStream, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns5", ns.ToString());

    auto subkey_iter = iter.GetSubKeyIterator();
    ASSERT_TRUE(subkey_iter);
    std::vector<std::string> expected_values = {"x0", "x1", "x2"};
    std::reverse(expected_values.begin(), expected_values.end());
    for (subkey_iter->Seek(); subkey_iter->Valid(); subkey_iter->Next()) {
      if (expected_values.empty()) {
        FAIL() << "Unexpected value: " << subkey_iter->Value().ToString();
      }
      std::vector<std::string> elems;
      auto s = redis::DecodeRawStreamEntryValue(subkey_iter->Value().ToString(), &elems);
      ASSERT_TRUE(s.IsOK() && !elems.empty());
      ASSERT_EQ(expected_values.back(), elems[0]);
      expected_values.pop_back();
    }
    ASSERT_TRUE(expected_values.empty());
  }
}

TEST_F(DBIteratorTest, BasicBitmap) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());
  auto prefix = ComposeNamespaceKey("test_ns6", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    ASSERT_EQ(kRedisBitmap, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns6", ns.ToString());

    auto subkey_iter = iter.GetSubKeyIterator();
    ASSERT_TRUE(subkey_iter);
    std::vector<std::string> expected_values = {"\x1", "\x1", "\x1"};
    for (subkey_iter->Seek(); subkey_iter->Valid(); subkey_iter->Next()) {
      if (expected_values.empty()) {
        FAIL() << "Unexpected value: " << subkey_iter->Value().ToString();
      }
      ASSERT_EQ(expected_values.back(), subkey_iter->Value().ToString());
      expected_values.pop_back();
    }
    ASSERT_TRUE(expected_values.empty());
  }
}

TEST_F(DBIteratorTest, BasicJSON) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());

  std::vector<std::string> expected_keys = {"json-1", "json-2", "json-3"};
  std::reverse(expected_keys.begin(), expected_keys.end());
  auto prefix = ComposeNamespaceKey("test_ns7", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    if (expected_keys.empty()) {
      FAIL() << "Unexpected key: " << iter.Key().ToString();
    }
    ASSERT_EQ(kRedisJson, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns7", ns.ToString());
    ASSERT_EQ(expected_keys.back(), key.ToString());
    expected_keys.pop_back();
    // Make sure there is no subkey iterator
    ASSERT_TRUE(!iter.GetSubKeyIterator());
  }
  // Make sure all keys are iterated except the expired one: "json-4"
  ASSERT_TRUE(expected_keys.empty());
}

TEST_F(DBIteratorTest, BasicSortedInt) {
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions());

  auto prefix = ComposeNamespaceKey("test_ns8", "", storage_->IsSlotIdEncoded());
  for (iter.Seek(prefix); iter.Valid() && iter.Key().starts_with(prefix); iter.Next()) {
    ASSERT_EQ(kRedisSortedint, iter.Type());
    auto [ns, key] = iter.UserKey();
    ASSERT_EQ("test_ns8", ns.ToString());

    auto subkey_iter = iter.GetSubKeyIterator();
    ASSERT_TRUE(subkey_iter);
    std::vector<uint64_t> expected_keys = {1, 2, 3};
    std::reverse(expected_keys.begin(), expected_keys.end());
    for (subkey_iter->Seek(); subkey_iter->Valid(); subkey_iter->Next()) {
      auto value = DecodeFixed64(subkey_iter->UserKey().data());
      if (expected_keys.empty()) {
        FAIL() << "Unexpected value: " << value;
      }
      ASSERT_EQ(expected_keys.back(), value);
      expected_keys.pop_back();
    }
  }
}

class SlotIteratorTest : public TestBase {
 protected:
  explicit SlotIteratorTest() = default;
  ~SlotIteratorTest() override = default;
  void SetUp() override { storage_->GetConfig()->slot_id_encoded = true; }
};

TEST_F(SlotIteratorTest, LiveKeys) {
  redis::String string(storage_.get(), kDefaultNamespace);
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  std::vector<std::string> keys = {"{x}a", "{x}b", "{y}c", "{y}d", "{x}e"};
  for (const auto &key : keys) {
    string.Set(*ctx_, key, "1");
  }

  std::set<std::string> same_slot_keys;
  auto slot_id = GetSlotIdFromKey(keys[0]);
  for (const auto &key : keys) {
    if (GetSlotIdFromKey(key) == slot_id) {
      same_slot_keys.insert(key);
    }
  }
  engine::DBIterator iter(*ctx_, rocksdb::ReadOptions(), slot_id);
  int count = 0;
  for (iter.Seek(); iter.Valid(); iter.Next()) {
    auto [_, user_key] = iter.UserKey();
    ASSERT_EQ(slot_id, GetSlotIdFromKey(user_key.ToString()));
    count++;
  }
  ASSERT_EQ(count, same_slot_keys.size());

  engine::WALIterator wal_iter(storage_.get(), slot_id);
  count = 0;
  for (wal_iter.Seek(start_seq + 1); wal_iter.Valid(); wal_iter.Next()) {
    auto item = wal_iter.Item();
    if (item.type == engine::WALItem::Type::kTypePut) {
      auto [_, user_key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
      ASSERT_EQ(slot_id, GetSlotIdFromKey(user_key.ToString())) << user_key.ToString();
      count++;
    }
  }
  ASSERT_EQ(count, same_slot_keys.size());
}

class WALIteratorTest : public TestBase {
 protected:
  explicit WALIteratorTest() = default;
  ~WALIteratorTest() override = default;
  void SetUp() override {}
};

TEST_F(WALIteratorTest, BasicString) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  redis::String string(storage_.get(), "test_ns0");
  string.Set(*ctx_, "a", "1");
  string.MSet(*ctx_, {{"b", "2"}, {"c", "3"}});
  ASSERT_TRUE(string.Del(*ctx_, "b").ok());

  std::vector<std::string> put_keys, delete_keys;
  auto expected_put_keys = {"a", "b", "c"};
  auto expected_delete_keys = {"b"};

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
        ASSERT_EQ(ns.ToString(), "test_ns0");
        put_keys.emplace_back(key.ToString());
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisString);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
        ASSERT_EQ(ns.ToString(), "test_ns0");
        delete_keys.emplace_back(key.ToString());
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }
  ASSERT_EQ(expected_put_keys.size(), put_keys.size());
  ASSERT_EQ(expected_delete_keys.size(), delete_keys.size());
  ASSERT_TRUE(std::equal(expected_put_keys.begin(), expected_put_keys.end(), put_keys.begin()));
  ASSERT_TRUE(std::equal(expected_delete_keys.begin(), expected_delete_keys.end(), delete_keys.begin()));
}

TEST_F(WALIteratorTest, BasicHash) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  redis::Hash hash(storage_.get(), "test_ns1");
  uint64_t ret = 0;
  hash.MSet(*ctx_, "hash-1", {{"f0", "v0"}, {"f1", "v1"}, {"f2", "v2"}, {"f3", "v3"}}, false, &ret);
  uint64_t deleted_cnt = 0;
  hash.Delete(*ctx_, "hash-1", {"f0"}, &deleted_cnt);

  // Delete will put meta key again
  auto expected_put_keys = {"hash-1", "hash-1"};
  // Sub key will be putted in reverse order
  auto expected_put_fields = {"f3", "f2", "f1", "f0"};
  auto expected_delete_fields = {"f0"};
  std::vector<std::string> put_keys, put_fields, delete_fields;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::PrimarySubkey)) {
          InternalKey internal_key(item.key, storage_->IsSlotIdEncoded());
          put_fields.emplace_back(internal_key.GetSubKey().ToString());
        } else if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::Metadata)) {
          auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
          ASSERT_EQ(ns.ToString(), "test_ns1");
          put_keys.emplace_back(key.ToString());
        }
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisHash);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        InternalKey internal_key(item.key, storage_->IsSlotIdEncoded());
        delete_fields.emplace_back(internal_key.GetSubKey().ToString());
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }
  ASSERT_EQ(expected_put_keys.size(), put_keys.size());
  ASSERT_EQ(expected_put_fields.size(), put_fields.size());
  ASSERT_EQ(expected_delete_fields.size(), delete_fields.size());
  ASSERT_TRUE(std::equal(expected_put_keys.begin(), expected_put_keys.end(), put_keys.begin()));
  ASSERT_TRUE(std::equal(expected_put_fields.begin(), expected_put_fields.end(), put_fields.begin()));
  ASSERT_TRUE(std::equal(expected_delete_fields.begin(), expected_delete_fields.end(), delete_fields.begin()));
}

TEST_F(WALIteratorTest, BasicSet) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();

  uint64_t ret = 0;
  redis::Set set(storage_.get(), "test_ns2");
  set.Add(*ctx_, "set-1", {"e0", "e1", "e2"}, &ret);
  uint64_t removed_cnt = 0;
  set.Remove(*ctx_, "set-1", {"e0", "e1"}, &removed_cnt);

  auto expected_put_keys = {"set-1", "set-1"};
  auto expected_put_members = {"e0", "e1", "e2"};
  auto expected_delete_members = {"e0", "e1"};
  std::vector<std::string> put_keys, put_members, delete_members;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::PrimarySubkey)) {
          InternalKey internal_key(item.key, storage_->IsSlotIdEncoded());
          put_members.emplace_back(internal_key.GetSubKey().ToString());
        } else if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::Metadata)) {
          auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
          ASSERT_EQ(ns.ToString(), "test_ns2");
          put_keys.emplace_back(key.ToString());
        }
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisSet);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        InternalKey internal_key(item.key, storage_->IsSlotIdEncoded());
        delete_members.emplace_back(internal_key.GetSubKey().ToString());
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }

  ASSERT_EQ(expected_put_keys.size(), put_keys.size());
  ASSERT_EQ(expected_put_members.size(), put_members.size());
  ASSERT_EQ(expected_delete_members.size(), delete_members.size());
  ASSERT_TRUE(std::equal(expected_put_keys.begin(), expected_put_keys.end(), put_keys.begin()));
  ASSERT_TRUE(std::equal(expected_put_members.begin(), expected_put_members.end(), put_members.begin()));
  ASSERT_TRUE(std::equal(expected_delete_members.begin(), expected_delete_members.end(), delete_members.begin()));
}

TEST_F(WALIteratorTest, BasicZSet) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  uint64_t ret = 0;
  redis::ZSet zset(storage_.get(), "test_ns3");
  auto mscores = std::vector<MemberScore>{{"z0", 0}, {"z1", 1}, {"z2", 2}};
  zset.Add(*ctx_, "zset-1", ZAddFlags(), &mscores, &ret);
  uint64_t removed_cnt = 0;
  zset.Remove(*ctx_, "zset-1", {"z0"}, &removed_cnt);

  auto expected_put_keys = {"zset-1", "zset-1"};
  auto expected_put_members = {"z2", "z1", "z0"};
  // member and score
  int expected_delete_count = 2, delete_count = 0;
  std::vector<std::string> put_keys, put_members;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::PrimarySubkey)) {
          InternalKey internal_key(item.key, storage_->IsSlotIdEncoded());
          put_members.emplace_back(internal_key.GetSubKey().ToString());
        } else if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::Metadata)) {
          auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
          ASSERT_EQ(ns.ToString(), "test_ns3");
          put_keys.emplace_back(key.ToString());
        }
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisZSet);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        delete_count++;
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }

  ASSERT_EQ(expected_put_keys.size(), put_keys.size());
  ASSERT_EQ(expected_put_members.size(), put_members.size());
  ASSERT_EQ(expected_delete_count, delete_count);
  ASSERT_TRUE(std::equal(expected_put_keys.begin(), expected_put_keys.end(), put_keys.begin()));
  ASSERT_TRUE(std::equal(expected_put_members.begin(), expected_put_members.end(), put_members.begin()));
}

TEST_F(WALIteratorTest, BasicList) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  uint64_t ret = 0;
  redis::List list(storage_.get(), "test_ns4");
  list.Push(*ctx_, "list-1", {"l0", "l1", "l2", "l3", "l4"}, false, &ret);
  ASSERT_TRUE(list.Trim(*ctx_, "list-1", 2, 4).ok());

  auto expected_put_keys = {"list-1", "list-1"};
  auto expected_put_values = {"l0", "l1", "l2", "l3", "l4"};
  auto expected_delete_count = 2, delete_count = 0;
  std::vector<std::string> put_keys, put_values;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::PrimarySubkey)) {
          put_values.emplace_back(item.value);
        } else if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::Metadata)) {
          auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
          ASSERT_EQ(ns.ToString(), "test_ns4");
          put_keys.emplace_back(key.ToString());
        }
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisList);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        delete_count++;
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }

  ASSERT_EQ(expected_put_keys.size(), put_keys.size());
  ASSERT_EQ(expected_put_values.size(), put_values.size());
  ASSERT_EQ(expected_delete_count, delete_count);
  ASSERT_TRUE(std::equal(expected_put_keys.begin(), expected_put_keys.end(), put_keys.begin()));
  ASSERT_TRUE(std::equal(expected_put_values.begin(), expected_put_values.end(), put_values.begin()));
}

TEST_F(WALIteratorTest, BasicStream) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  redis::Stream stream(storage_.get(), "test_ns5");
  redis::StreamEntryID ret;
  redis::StreamAddOptions options;
  options.next_id_strategy = std::make_unique<redis::AutoGeneratedEntryID>();
  stream.Add(*ctx_, "stream-1", options, {"x0"}, &ret);
  stream.Add(*ctx_, "stream-1", options, {"x1"}, &ret);
  stream.Add(*ctx_, "stream-1", options, {"x2"}, &ret);
  uint64_t deleted = 0;
  ASSERT_TRUE(stream.DeleteEntries(*ctx_, "stream-1", {ret}, &deleted).ok());

  auto expected_put_keys = {"stream-1", "stream-1", "stream-1", "stream-1"};
  auto expected_put_values = {"x0", "x1", "x2"};
  int delete_count = 0;
  std::vector<std::string> put_keys, put_values;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::Stream)) {
          std::vector<std::string> elems;
          auto s = redis::DecodeRawStreamEntryValue(item.value, &elems);
          ASSERT_TRUE(s.IsOK() && !elems.empty());
          put_values.emplace_back(elems[0]);
        } else if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::Metadata)) {
          auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
          ASSERT_EQ(ns.ToString(), "test_ns5");
          put_keys.emplace_back(key.ToString());
        }
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisStream);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        delete_count++;
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }

  ASSERT_EQ(expected_put_keys.size(), put_keys.size());
  ASSERT_EQ(expected_put_values.size(), put_values.size());
  ASSERT_EQ(deleted, delete_count);
  ASSERT_TRUE(std::equal(expected_put_keys.begin(), expected_put_keys.end(), put_keys.begin()));
  ASSERT_TRUE(std::equal(expected_put_values.begin(), expected_put_values.end(), put_values.begin()));
}

TEST_F(WALIteratorTest, BasicBitmap) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();

  redis::Bitmap bitmap(storage_.get(), "test_ns6");
  bool ret = false;
  bitmap.SetBit(*ctx_, "bitmap-1", 0, true, &ret);
  bitmap.SetBit(*ctx_, "bitmap-1", 8 * 1024, true, &ret);
  bitmap.SetBit(*ctx_, "bitmap-1", 2 * 8 * 1024, true, &ret);

  auto expected_put_values = {"\x1", "\x1", "\x1"};
  std::vector<std::string> put_values;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::PrimarySubkey)) {
          put_values.emplace_back(item.value);
        }
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisBitmap);
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }
  ASSERT_EQ(expected_put_values.size(), put_values.size());
  ASSERT_TRUE(std::equal(expected_put_values.begin(), expected_put_values.end(), put_values.begin()));
}

TEST_F(WALIteratorTest, BasicJSON) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  redis::Json json(storage_.get(), "test_ns7");
  json.Set(*ctx_, "json-1", "$", "{\"a\": 1, \"b\": 2}");
  json.Set(*ctx_, "json-2", "$", "{\"a\": 1, \"b\": 2}");
  json.Set(*ctx_, "json-3", "$", "{\"a\": 1, \"b\": 2}");

  size_t result = 0;
  ASSERT_TRUE(json.Del(*ctx_, "json-3", "$", &result).ok());

  auto expected_put_keys = {"json-1", "json-2", "json-3"};
  auto expected_delete_keys = {"json-3"};
  std::vector<std::string> put_keys, delete_keys;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        ASSERT_EQ(item.column_family_id, static_cast<uint32_t>(ColumnFamilyID::Metadata));
        auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
        ASSERT_EQ(ns.ToString(), "test_ns7");
        put_keys.emplace_back(key.ToString());
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisJson);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        ASSERT_EQ(item.column_family_id, static_cast<uint32_t>(ColumnFamilyID::Metadata));
        auto [ns, key] = ExtractNamespaceKey(item.key, storage_->IsSlotIdEncoded());
        ASSERT_EQ(ns.ToString(), "test_ns7");
        delete_keys.emplace_back(key.ToString());
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }

  ASSERT_EQ(expected_put_keys.size(), put_keys.size());
  ASSERT_EQ(expected_delete_keys.size(), delete_keys.size());
  ASSERT_TRUE(std::equal(expected_put_keys.begin(), expected_put_keys.end(), put_keys.begin()));
  ASSERT_TRUE(std::equal(expected_delete_keys.begin(), expected_delete_keys.end(), delete_keys.begin()));
}

TEST_F(WALIteratorTest, BasicSortedInt) {
  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  redis::Sortedint sortedint(storage_.get(), "test_ns8");
  uint64_t ret = 0;
  sortedint.Add(*ctx_, "sortedint-1", {1, 2, 3}, &ret);
  uint64_t removed_cnt = 0;
  sortedint.Remove(*ctx_, "sortedint-1", {2}, &removed_cnt);

  std::vector<uint64_t> expected_values = {1, 2, 3}, put_values;
  std::vector<uint64_t> expected_delete_values = {2}, delete_values;

  engine::WALIterator iter(storage_.get());

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    auto item = iter.Item();
    switch (item.type) {
      case engine::WALItem::Type::kTypePut: {
        if (item.column_family_id == static_cast<uint32_t>(ColumnFamilyID::PrimarySubkey)) {
          const InternalKey internal_key(item.key, storage_->IsSlotIdEncoded());
          auto value = DecodeFixed64(internal_key.GetSubKey().data());
          put_values.emplace_back(value);
        }
        break;
      }
      case engine::WALItem::Type::kTypeLogData: {
        redis::WriteBatchLogData log_data;
        ASSERT_TRUE(log_data.Decode(item.key).IsOK());
        ASSERT_EQ(log_data.GetRedisType(), kRedisSortedint);
        break;
      }
      case engine::WALItem::Type::kTypeDelete: {
        const InternalKey internal_key(item.key, storage_->IsSlotIdEncoded());
        auto value = DecodeFixed64(internal_key.GetSubKey().data());
        delete_values.emplace_back(value);
        break;
      }
      default:
        FAIL() << "Unexpected wal item type" << uint8_t(item.type);
    }
  }
  ASSERT_EQ(expected_values.size(), put_values.size());
  ASSERT_EQ(expected_delete_values.size(), delete_values.size());
  ASSERT_TRUE(std::equal(expected_values.begin(), expected_values.end(), put_values.begin()));
  ASSERT_TRUE(std::equal(expected_delete_values.begin(), expected_delete_values.end(), delete_values.begin()));
}

TEST_F(WALIteratorTest, NextSequence) {
  std::vector<rocksdb::SequenceNumber> expected_next_sequences;
  std::set<rocksdb::SequenceNumber> next_sequences_set;

  auto start_seq = storage_->GetDB()->GetLatestSequenceNumber();
  uint64_t ret = 0;
  redis::List list(storage_.get(), "test_ns2");
  list.Push(*ctx_, "list-1", {"l0", "l1", "l2", "l3", "l4"}, false, &ret);
  expected_next_sequences.emplace_back(storage_->GetDB()->GetLatestSequenceNumber() + 1);
  list.Push(*ctx_, "list-2", {"l0", "l1", "l2"}, false, &ret);
  expected_next_sequences.emplace_back(storage_->GetDB()->GetLatestSequenceNumber() + 1);
  ASSERT_TRUE(list.Trim(*ctx_, "list-1", 2, 4).ok());
  expected_next_sequences.emplace_back(storage_->GetDB()->GetLatestSequenceNumber() + 1);

  engine::WALIterator iter(storage_.get());

  ASSERT_EQ(iter.NextSequenceNumber(), 0);

  for (iter.Seek(start_seq + 1); iter.Valid(); iter.Next()) {
    next_sequences_set.emplace(iter.NextSequenceNumber());
  }

  std::vector<rocksdb::SequenceNumber> next_sequences(next_sequences_set.begin(), next_sequences_set.end());

  ASSERT_EQ(expected_next_sequences.size(), next_sequences.size());
  ASSERT_TRUE(std::equal(expected_next_sequences.begin(), expected_next_sequences.end(), next_sequences.begin()));
}
