#include "search_source.h"

#include <search/base/yx_search.h>

#include <saas/rtyserver/config/config.h>
#include <saas/rtyserver/config/searcher_config.h>

TRTYSearchSource::TRTYSearchSource(const TString& dirName, IIndexController::TPtr indexController, const TRTYServerConfig& config)
    : Config(config)
    , IndexController(indexController)
    , DirName(dirName)
    , SearcherId(indexController->GetSearcherId())
{
    IsMemorySearch = (IndexController->GetType() == IIndexController::MEMORY);
    IsCustomSearch = !(IndexController->GetCommonSearch());
    CHECK_WITH_LOG(IndexController->HasSearcher());
    MetaCacheOn = CacheStatus = (Config.GetSearcherConfig().CacheOptions.UseCache && !IsMemorySearch);
}

ui32 TRTYSearchSource::DecodeDocId(const TDocHandle& docIdFromMessage) const {
    VERIFY_WITH_LOG(!!docIdFromMessage, "Incorrect docId from message");
    if (IsCustom()) {
        return docIdFromMessage.IntHash();
    } else {
        const auto baseCommonSearch = CheckedCast<TBaseCommonSearch*>(IndexController->GetCommonSearch());
        CHECK_WITH_LOG(baseCommonSearch);
        return baseCommonSearch->GetDocIdStats().ResolveDocIdFromMeta(docIdFromMessage);
    }
}

void TRTYSearchSource::SetActive(bool value, bool force) {
    if (IsActive() && !value && !force) {
        Y_ASSERT(0); // should not happen?
        ERROR_LOG << "Unexpected SearchSource.Active value for " << DirName << Endl;
    }
    if (!IsActive() && value) {
        Prefetch();
    }
    Active = value;
    INFO_LOG << "Set search source " << DirName << " " << (value ? "active" : "inactive") << Endl;
}

bool TRTYSearchSource::IsActive() const {
    return Active.Defined() && Active.GetRef();
}

bool TRTYSearchSource::IsMem() const {
    return IsMemorySearch;
}

bool TRTYSearchSource::IsCustom() const {
    return IsCustomSearch;
}

bool TRTYSearchSource::IsDiskSearch() const {
    return IndexController->GetRealm() == NRTYServer::ERealm::Realtime;
}

TString TRTYSearchSource::GetSourceDescr() const {
    if (IsMem()) {
        return "Memory";
    }
    if (IsDiskSearch()) {
        return "DiskSearch";
    }
    return "Disk";
}

void TRTYSearchSource::Prefetch() const {
    INFO_LOG << "Prefetching search source " << GetDirName() << " started" << Endl;
    const TInstant start = Now();
    IndexController->Prefetch();
    const TInstant finish = Now();
    INFO_LOG << "Prefetching search source " << GetDirName() << " took " << (finish - start) << Endl;
}
