#pragma once

#include <saas/rtyserver/indexer_core/abstract_model.h>

class TKeysComponentConfig;
class IDocProcessor;

class TKeysIndexManager: public NRTYServer::IIndexComponentManager {
private:
    const TKeysComponentConfig* Config;

    static const TString KeyNameCgi;

public:
    using THash = TFixedSizeHashable<16>;

    class TIterator: public TAtomicRefCount<TIterator> {
    public:
        using TPtr = TIntrusivePtr<TIterator>;
        virtual ~TIterator() {}
        virtual bool Valid() const = 0;
        virtual void Next() = 0;
        virtual void SkipTo(SUPERLONG pos) = 0;
        virtual SUPERLONG GetPosition() const = 0;
        virtual TPtr Clone() const = 0;
    };

public:
    TKeysIndexManager(const TRTYServerConfig& config);
    virtual ~TKeysIndexManager();

    virtual void InitInteractions(const NRTYServer::IIndexManagersStorage& storage) override;
    virtual ui32 RemoveDocids(const TVector<ui32>& docids) override;
    virtual ui32 GetDocumentsCount() const override;

    virtual bool UpdateDoc(ui32 /*docId*/, const TParsedDocument::TPtr /*doc*/) override {
        return true;
    }

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

    bool SearchImpl(const TRTYSearchRequestContext& context, const IIndexController& controller, TVector<TDocIdCandidate>& docIds, TMessagesCollector& errors) const;

private:
    void ExtractRequestParams(const TCgiParameters& cgi, TVector<TDocSearchInfo>& searchInfos,  TString& keyName) const;

public:
    virtual bool GetData(const TString& keyName, const TString& value, const IDocProcessor* filter, TSet<SUPERLONG>& result) const = 0;
    virtual bool HasKey(const TString& keyName, const TString& value) const = 0;
    virtual TIterator::TPtr CreateIterator(const TString& keyName, const TString& value, const IDocProcessor* filter) const = 0;
    virtual void GetKeyValues(const TString& keyName, TSet<TString>& result) const = 0;

    inline bool GetData(const TString& keyName, const THash& keyHash, const IDocProcessor* filter, TSet<SUPERLONG>& result) const {
        return GetData(keyName, keyHash.Quote(), filter, result);
    }

    inline bool HasKey(const TString& keyName, const THash& keyHash) const {
        return HasKey(keyName, keyHash.Quote());
    }

    inline TIterator::TPtr CreateIterator(const TString& keyName, const THash& keyHash, const IDocProcessor* filter) const {
        return CreateIterator(keyName, keyHash.Quote(), filter);
    }
};
