#include "gtest/gtest.h"
#include "db/NewDB.h"  // NewDB 的头文件
#include "leveldb/env.h"
#include "leveldb/db.h"
#include "db/write_batch_internal.h"
#include <iostream>
#include <random>
#include <ctime>
#include <thread>

using namespace leveldb;

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

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

// 全局的随机数引擎
std::default_random_engine rng;

// 设置随机种子
void SetGlobalSeed(unsigned seed) {
    rng.seed(seed);
}

// 生成随机字符串
std::string GenerateRandomString(size_t length) {
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";

    std::uniform_int_distribution<int> dist(0, sizeof(alphanum) - 2);

    std::string str(length, 0);
    for (size_t i = 0; i < length; ++i) {
        str[i] = alphanum[dist(rng)];
    }
    return str;
}

std::string testdbname = "dbtest1";

TEST(TestNewDB, ConstancyTest) {
    // 创建 NewDB 实例
    NewDB* db;
    ASSERT_TRUE(OpenNewDB(testdbname, &db).ok());

    db->CreateIndexOnField("address");

    delete db;

    // 创建 NewDB 实例
    NewDB* db_2;
    ASSERT_TRUE(OpenNewDB(testdbname, &db_2).ok());

    std::string key = "k_" + GenerateRandomString(10);
    FieldArray fields = {
        {"name", GenerateRandomString(5)},
        {"address", GenerateRandomString(15)},
        {"phone", GenerateRandomString(11)}
    };
    std::string index_key = db->ConstructIndexKey(key, fields[1]);
    db->Put_fields(WriteOptions(), key, fields);

    delete db_2;

    // 创建 DB 实例
    DB* index_db;
    ASSERT_TRUE(OpenDB(testdbname + "_index", &index_db).ok());

    std::string prefix = index_key;
    leveldb::Iterator* iter = index_db->NewIterator(leveldb::ReadOptions());
    for(iter->Seek(prefix); iter->Valid() && iter->key().starts_with(prefix); iter->Next()){
        Slice find_key = iter->key();
        EXPECT_EQ(find_key.ToString(), index_key);
    }
    delete iter;
    delete index_db;    
}

int main(int argc, char** argv) {
    // 设置全局随机种子
    SetGlobalSeed(static_cast<unsigned>(time(nullptr)));
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}