#include <chrono>
#include <iomanip>
#include <iostream>
#include <leveldb/db.h>
#include <leveldb/options.h>
#include <numeric>
#include <sstream>
#include <string>
#include <thread>
#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中每个字段值唯一
      }
    }
  }

  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(ConcurrentTest, Basic) {
  DB* db;
  WriteOptions writeOptions;
  ReadOptions readOptions;
  if (!OpenDB("testdb6", &db).ok()) {
    std::cerr << "open db failed" << std::endl;
    abort();
  }
  const int numThreads = 10;
  const int numOperationsPerThread = 100;
  std::vector<std::thread> threads;

  // 创建写线程
  for (int i = 0; i < numThreads / 2; ++i) {
    threads.emplace_back([&db, i, numOperationsPerThread]() {
      WriteOptions writeOptions;
      for (int j = 0; j < numOperationsPerThread; ++j) {
        std::string key = "key_" + std::to_string(i * numOperationsPerThread + j);
        FieldArray fields = {
            {"name", "Customer" + std::to_string(i * numOperationsPerThread + j)},
            {"address", "Address" + std::to_string(i * numOperationsPerThread + j)},
            {"phone", "1234567890"}
        };
        db->Put_Fields(writeOptions, key, fields);
      }
    });
  }

  // 创建读线程
  for (int i = 0; i < numThreads / 2; ++i) {
    threads.emplace_back([&db, i, numOperationsPerThread]() {
      ReadOptions readOptions;
      Field queryField = {"name", "Customer"};
      for (int j = 0; j < numOperationsPerThread; ++j) {
        std::string key = "key_" + std::to_string(i * numOperationsPerThread + j % (numOperationsPerThread * (numThreads / 2)));
        FieldArray fields;
        db->Get_Fields(readOptions, key, fields);
        bool found = false;
        for (const auto& field : fields) {
          if (field.name == queryField.name &&
              field.value.substr(0, queryField.value.size()) == queryField.value) {  // 部分匹配以测试前缀搜索的效果
            found = true;
            break;
          }
        }
        // 添加断言检查读取的正确性
        // ASSERT_TRUE(found);
      }

      // 测试查找功能
      //      std::vector<std::string> foundKeys = db.FindKeysByField(queryField);
      // 添加断言检查查找的正确性
      // ASSERT_EQ(foundKeys.size(), expectedSize);
    });
  }

  // 等待所有线程完成
  for (auto& thread : threads) {
    thread.join();
  }

  delete db;
}

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}