#pragma once

#include <saas/rtyserver/model/index.h>
#include <saas/util/types/interval.h>

#include <util/generic/noncopyable.h>
#include <util/generic/maybe.h>

struct TRTYServerConfig;
class TDocHandle;

class TRTYSearchSource: TNonCopyable {
private:
    const TRTYServerConfig& Config;
    IIndexController::TPtr IndexController;
    bool IsMemorySearch;
    bool IsCustomSearch;
    TString DirName;
    bool CacheStatus, MetaCacheOn;
    TMutex Mutex;
    TString SearcherId;
    TMaybeFail<bool> Active;

private:
    void Prefetch() const;

public:
    typedef TAtomicSharedPtr<TRTYSearchSource> TPtr;

public:
    TInterval<double> GetPruneInterval() const {
        return IndexController->GetPruneInterval();
    }

    void SetActive(bool value, bool force = false);
    bool IsActive() const;

    ui32 GetDocsCount() const {
        return IndexController->GetDocumentsCount();
    }
    ui32 GetDocsCount(const TInterval<double>& interval) const {
        return IndexController->GetDocsCountInInterval(interval);
    }
    ui32 GetDeletedDocsCount() const {
        return IndexController->GetDocumentsCount(true) - IndexController->GetDocumentsCount(false);
    }
    ui32 GetSearchableDocsCount() const {
        return IndexController->GetSearchableDocumentsCount();
    }
    ui32 GetSearchPriority() const {
        return IndexController->GetSearchPriority() + (IsActive() ? 1 : 0);
    }
    ui32 GetState() const {
        return IndexController->GetState();
    }

    const TString& GetDirName() const {
        return DirName;
    }
    const TString& GetSearcherId() const {
        return SearcherId;
    }

    IIndexController::TPtr GetIndexController() const {
        VERIFY_WITH_LOG(IndexController, "crash: empty index controller");
        return IndexController;
    }

    bool IsDeletedDoc(const TDocHandle& docId) const {
        if (IsMemorySearch)
            return false;
        else {
            return IndexController->IsRemoved( DecodeDocId(docId) );
        }
    }

    bool GetCacheStatus() {
        TGuard<TMutex> g(Mutex);
        return CacheStatus && !IsMemorySearch;
    }

    ui32 DecodeDocId(const TDocHandle& docIdFromMessage) const;

    bool IsMem() const;
    bool IsCustom() const;
    bool IsDiskSearch() const;
    TString GetSourceDescr() const;

    TRTYSearchSource(const TString& dirName, IIndexController::TPtr indexController, const TRTYServerConfig& config);
};

using TSearchers = TMap<TString, TAtomicSharedPtr<TRTYSearchSource>>;
using TSearchersVector = TVector<TAtomicSharedPtr<TRTYSearchSource>>;
