#include "testdb/testdb.h"
#include "db/db_impl.h"
#include <memory>
#include "leveldb/status.h"
#include "testdb.h"
using namespace testdb;

Status testDB::OpentestDB(Options& options,
                            const std::string& name, testDB** dbptr) {
    // options.env->CreateDir("./abc")
    if(*dbptr == nullptr){
        return Status::NotSupported(name, "new a testDb first\n");
    }

    //
    Status status;
    DB *indexdb, *kvdb, *metadb;
    // options.block_cache = NewLRUCache(ULONG_MAX);
    // options.max_open_files = 1000;
    // options.write_buffer_size = 512 * 1024 * 1024;
    // options.env = getPosixEnv();
    // status = Open(options, name+"_indexDB", &indexdb);
    // if(!status.ok()) return status;
    // (*dbptr)->indexDB_ = indexdb;
    
    // options.env = getPosixEnv();
    status = DB::Open(options, name+"_kvDB", &kvdb);
    if(!status.ok()) return status;
    (*dbptr)->kvDB_ = kvdb;

    // options.env = getPosixEnv();
    // status = Open(options, name+"_metaDB", &metadb);
    // if(!status.ok()) return status;
    // (*dbptr)->metaDB_ = metadb;

    (*dbptr)->dbname_ = name;

    // status = (*dbptr)->Recover();

    (*dbptr)->options_ = &options;
    (*dbptr)->env_ = options.env;
    return status;
}

Status testDB::Put(const WriteOptions &options, const Slice &key, const Slice &value) {
    return kvDB_->Put(options, key, value);
}

Status testDB::PutFields(const WriteOptions &, const Slice &key, const FieldArray &tests) {
    return Status::OK();
}

Status testDB::Delete(const WriteOptions &options, const Slice &key) {
    return kvDB_->Delete(options, key);
}

Status testDB::Write(const WriteOptions &options, WriteBatch *updates) {
    return kvDB_->Write(options, updates);
}

Status testDB::Get(const ReadOptions &options, const Slice &key, std::string *value) {
    return kvDB_->Get(options, key, value);
}

Status testDB::GetFields(const ReadOptions &options, const Slice &key, FieldArray *tests) {
    return Status::OK();
}

std::vector<std::string> testDB::FindKeysByField(Field &test) {
    return std::vector<std::string>();
}

Iterator * testDB::NewIterator(const ReadOptions &options) {
    return kvDB_->NewIterator(options);
}

const Snapshot * testDB::GetSnapshot() {
    return kvDB_->GetSnapshot();
}

void testDB::ReleaseSnapshot(const Snapshot *snapshot) {
    kvDB_->ReleaseSnapshot(snapshot);
}

bool testDB::GetProperty(const Slice &property, std::string *value) {
    return kvDB_->GetProperty(property, value);
}

void testDB::GetApproximateSizes(const Range *range, int n, uint64_t *sizes) {
    kvDB_->GetApproximateSizes(range, n, sizes);
}

void testDB::CompactRange(const Slice *begin, const Slice *end) {
    kvDB_->CompactRange(begin, end);
}

Status testdb::DestroyDB(const std::string& name, const Options& options) {
  Status s;
  s = leveldb::DestroyDB(name+"_kvDB", options);
  assert(s.ok());
//   s = leveldb::DestroyDB(name+"_indexDB", options);
//   assert(s.ok());
//   s = leveldb::DestroyDB(name+"_metaDB", options);
//   assert(s.ok());
  return s;
}

testDB::~testDB() {
    delete kvDB_;
    // delete indexDB_;
    // delete metaDB_;
}
