#pragma once

#include <util/generic/singleton.h>
#include <util/system/types.h>

class TDocHandle;

class ISearchLocker {
public:
    class ILock {
    public:
        virtual ~ILock() = default;
    };
    virtual ~ISearchLocker() = default;
    virtual ILock* GetSearchLock() = 0;
};

class ISearchAreaModifier: public ISearchLocker {
public:
    virtual ~ISearchAreaModifier() = default;

    virtual void StartTransaction(bool checkMain) = 0;
    virtual void FinishTransaction() = 0;

    virtual bool IsRemoved(const size_t indexId, const TDocHandle& docId) const = 0;
    virtual ui32 GetDocumentsCount(size_t indexId, bool withDeleted) const = 0;
    virtual ui32 GetTimestamp(size_t indexId, const TDocHandle& docId) const = 0;
    virtual bool DecodeDocId(const TDocHandle& docIdFromMessage, ui32& indexId, ui32& docId) const = 0;
    virtual ui32 DecodeDocId(const TDocHandle& docIdFromMessage, size_t indexId) const = 0;
};


class TSearchAreaModifier {
private:
    ISearchAreaModifier* SearchAreaModifier = nullptr;
public:
    void RegisterModifier(ISearchAreaModifier& searchAreaModifier) {
        SearchAreaModifier = &searchAreaModifier;
    }

    void ClearRegisterModifier() {
        SearchAreaModifier = nullptr;
    }

    ISearchAreaModifier* GetModifier() {
        return SearchAreaModifier;
    }
};

class TGuardOfTransactionSearchArea {
public:
    TGuardOfTransactionSearchArea(bool checkMain = false)
        : SearchAreaModifier(Singleton<TSearchAreaModifier>()->GetModifier())
    {
        if (SearchAreaModifier) {
            SearchAreaModifier->StartTransaction(checkMain);
        }
    }
    ~TGuardOfTransactionSearchArea() {
        if (SearchAreaModifier) {
            SearchAreaModifier->FinishTransaction();
        }
    }

private:
    ISearchAreaModifier* SearchAreaModifier = nullptr;
};
