#include "manager.h"
#include <saas/rtyserver/components/fullarchive/manager.h>
#include <saas/rtyserver/indexer_core/abstract_model.h>
#include <saas/library/mapping/mapping.h>

ui32 TMinHashToDocIdManager::GetIdUnsafe(const NSaas::TDocHash& hash) const {
    if (!HashTable) {
        return IUrlToDocIdManager::NotFound;
    }
    TString key = hash.Quote();
    ui32 pos = HashTable->Hash()->Get(key.c_str(), key.size());
    if (pos == NMinHash::TChdMinHashFunc::npos) {
        return IUrlToDocIdManager::NotFound;
    } else {
        return HashTable->Get(0, pos);
    }
}

bool TMinHashToDocIdManager::VerifyIdByHash(ui32 docId, const NSaas::TDocHash& hashToVerify) const {
    if (docId == IUrlToDocIdManager::NotFound) {
        return false;
    }
    auto urlHash = DDKManager->GetIdentifier(docId);
    if (urlHash != hashToVerify) {
        return false;
    }
    return true;
}


TDocIdCandidate TMinHashToDocIdManager::GetIdCandidateByDocInfo(const TDocSearchInfo& info) const {
    ui32 id = GetIdUnsafe(info.GetHash());
    TDocIdCandidate candidate(info);
    if (id != IUrlToDocIdManager::NotFound) {
        candidate.SetVerified(IsDocCandidateAlwaysVerified());
    }
    candidate.SetDocId(id);
    return candidate;
}


ui32 TMinHashToDocIdManager::GetIdByDocInfo(const TDocSearchInfo& info) const {
    return GetIdByHash(info.GetHash());
}

ui32 TMinHashToDocIdManager::GetIdByHash(const NSaas::TDocHash& hash) const {
    ui32 docId = GetIdUnsafe(hash);
    if (docId == IUrlToDocIdManager::NotFound) {
        return docId;
    }
    if (VerifyIdByHash(docId, hash)) {
        return docId;
    } else {
        return IUrlToDocIdManager::NotFound;
    }
}

ui32 TMinHashToDocIdManager::GetDocumentsCount() const {
    return -1;
}

void TMinHashToDocIdManager::InitInteractions(const NRTYServer::IIndexManagersStorage& storage) {
    DDKManager = storage.GetDDKManager();
}

bool TMinHashToDocIdManager::IsDocCandidateAlwaysVerified() const {
    return false;
}

bool TMinHashToDocIdManager::IsOpen() const {
    return !!HashTable;
}

bool TMinHashToDocIdManager::OpenTableFile() {
    if (IsOpen()) {
        Close();
    }
    if (!NFs::Exists(FileName)) {
        NOTICE_LOG << "File " << FileName << " does not exist" << Endl;
        return false;
    }

    try {
        HashTable.Reset(new NMinHash::TTable<ui32, NMinHash::TChdMinHashFunc>(FileName));
    } catch (...) {
        NOTICE_LOG << "Can't open hashtable data: " << CurrentExceptionMessage() << Endl;
        return false;
    }
    Size = HashTable->Hash()->Size();
    return true;
}

bool TMinHashToDocIdManager::DoOpen() {
    return OpenTableFile();
}

bool TMinHashToDocIdManager::DoClose() {
    if (!IsOpen()) {
        return true;
    }
    HashTable.Destroy();
    HashTable = nullptr;
    return true;
}

bool TMinHashToDocIdManager::GetDocInfo(const ui32 /*docId*/, NJson::TJsonValue& /*result*/) const {
    return false;
}

bool TMinHashToDocIdManager::UpdateDoc(ui32 /*docId*/, const TParsedDocument::TPtr /*doc*/) {
    return false;
}

ui32 TMinHashToDocIdManager::RemoveDocids(const TVector<ui32>& /*docids*/) {
    return 0;
};

ui32 TMinHashToDocIdManager::MarkDocIdsForDeleteUnsafe(const TVector<ui32>& /*docids*/, ui32 /*marker*/) {
    return 0;
}

ERTYSearchResult TMinHashToDocIdManager::DoSearch(const TRTYSearchRequestContext& /*context*/, ICustomReportBuilder& /*reportBuilder*/, const IIndexController& /*controller*/) const {
    return SR_NOT_FOUND;
}
