#pragma once

#include "builder.h"
#include "manager.h"

class TBaseGeneratorManager;
class IDDKManager;

namespace NJson {
    class TJsonValue;
}

namespace NRTYServer {
    class IIndexManagersStorage: public IIndexComponentManager {
    public:
        class ICallbacks {
        public:
            virtual ~ICallbacks() {}
            virtual void OnBeforeManagerClose(const IIndexComponentManager* manager) = 0;
            virtual void OnAfterManagerClose(const IIndexComponentManager* manager) = 0;
        };

    protected:
        ICallbacks* Callbacks = nullptr;
    protected:
        virtual const IIndexComponentManager* GetManagerImpl(const TString& name) const = 0;
    public:
        IIndexManagersStorage()
            : IIndexComponentManager("COMPONENTS_STORAGE")
        {
        }

        void InitCallbacks(ICallbacks* callbacks) {
            Callbacks = callbacks;
        };

        virtual void RegisterManager(const TString& name, THolder<IIndexComponentManager> manager) = 0;
        virtual void CheckDocumentsNumber(ui32 docsCount) const = 0;
        virtual bool GetDocInfo(const ui32 /* docId */, NJson::TJsonValue& /* result */) const { return false; }
        virtual bool HasIndexManager() const = 0;
        virtual const TBaseGeneratorManager* GetIndexManager() const = 0;
        virtual const IDDKManager* GetDDKManager() const = 0;

        template <class T> const T* GetManager(const TString& name) const {
            return dynamic_cast<const T*>(GetManagerImpl(name));
        };

        virtual ui32 GetDocumentsCount() const = 0;
    };

    class IIndexBuildersStorage {
    public:
        class ICallbacks {
        public:
            virtual ~ICallbacks() {}
            virtual void OnBeforeBuilderClose(const IIndexComponentBuilder* builder, const TString& name) = 0;
            virtual void OnAfterBuilderClose(const IIndexComponentBuilder* builder, const TString& name) = 0;
        };

    protected:
        ICallbacks* Callbacks = nullptr;

    protected:
        virtual IIndexComponentBuilder* GetBuilderImpl(const TString& name) const = 0;
    public:
        void InitCallbacks(ICallbacks* callbacks) {
            Callbacks = callbacks;
        };

        virtual ~IIndexBuildersStorage() {}

        virtual void RegisterBuilder(const TString& name, THolder<IIndexComponentBuilder> builder) = 0;

        template <class T> T* GetBuilder(const TString& name) const {
            return dynamic_cast<T*>(GetBuilderImpl(name));
        };
    };
}
