#include <chrono>
#include <iomanip>
#include <iostream>
#include <leveldb/db.h>
#include <leveldb/options.h>
#include <numeric>
#include <sstream>
#include <string>
#include <vector>

#include "leveldb/env.h"

#include "gtest/gtest.h"

using namespace leveldb;
// 根据字段值查找所有包含该字段的 key，遍历
std::vector<std::string> FindKeysByField(leveldb::DB* db, const Field& field) {
  std::vector<std::string> keys;
  leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());

  for (it->SeekToFirst(); it->Valid()   ; it->Next()) {
    std::string key = it->key().ToString();
    FieldArray fields;
    db->Get_Fields(leveldb::ReadOptions(), key, fields);
    for (const auto& f : fields) {
      if (f.name == field.name && f.value == field.value) {
        keys.push_back(key);
        break; // 假设每个key中每个字段值唯一
      }
    }
  }
  std::cout << "Found " << keys.size() << " keys" << std::endl;
  for (const auto& key : keys) {
    std::cout << "Found key: " << key << std::endl;
  }
  delete it;
  return keys;
}

Status OpenDB(std::string dbName, DB** db) {
  Options options;
  options.create_if_missing = true;
  return DB::Open(options, dbName, db);
}

TEST(TestSchema, Basic) {
  DB* db;
  WriteOptions writeOptions;
  ReadOptions readOptions;
  if (!OpenDB("testdb_function", &db).ok()) {
    std::cerr << "open db failed" << std::endl;
    abort();
  }
  std::string key0 = "k_0";
  std::string key1 = "k_1";
  std::string key2 = "k_2";
  std::string key3 = "k_3";
  FieldArray fields0 = {{"name", "myc&wxf"}};
  FieldArray fields1 = {
      {"name", "Customer1"},
      {"address", "IVhzIApeRb"},
      {"phone", "25-989-741-2988"}
  };
  FieldArray fields2 = {
      {"name", "Customer1"},
      {"address", "ecnu"},
      {"phone", "123456789"}
  };
  FieldArray fields3 = {
      {"name", "Customer2"},
      {"address", "ecnu"},
      {"phone", "11111"}
  };
  db->Put_Fields(leveldb::WriteOptions(), key0, fields0);
  db->Put_Fields(leveldb::WriteOptions(), key1, fields1);
  db->Put_Fields(leveldb::WriteOptions(), key2, fields2);
  db->Put_Fields(leveldb::WriteOptions(), key3, fields3);
  FieldArray fields_ret_0;
  FieldArray fields_ret_1;
  FieldArray fields_ret_2;
  FieldArray fields_ret_3;
  db->Get_Fields(leveldb::ReadOptions(), key0, fields_ret_0);
  db->Get_Fields(leveldb::ReadOptions(), key1, fields_ret_1);
  db->Get_Fields(leveldb::ReadOptions(), key2, fields_ret_2);
  db->Get_Fields(leveldb::ReadOptions(), key3, fields_ret_3);
  // 检查反序列化结果
  ASSERT_EQ(fields_ret_0.size(), fields0.size());
  for (size_t i = 0; i < fields_ret_0.size(); ++i) {
    ASSERT_EQ(fields_ret_0[i].name, fields0[i].name);
    ASSERT_EQ(fields_ret_0[i].value, fields0[i].value);
  }
  ASSERT_EQ(fields_ret_1.size(), fields1.size());
  for (size_t i = 0; i < fields_ret_1.size(); ++i) {
    ASSERT_EQ(fields_ret_1[i].name, fields1[i].name);
//    ASSERT_EQ(fields_ret_1[i].value, fields1[i].value);
  }
  // 测试查找功能
  Field query_field = {"name", "Customer1"};
  std::vector<std::string> found_keys = FindKeysByField(db, query_field);
  // 删除查找到的第一个 key
  const std::string& key = found_keys[0];
  db->Delete(leveldb::WriteOptions(), key);
  // 再次查找
  std::vector<std::string> found_deleted_keys = FindKeysByField(db, query_field);
  // 关闭数据库
  delete db;
}
int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}