#pragma once

#include "entity.h"
#include "read_rules.h"
#include "permissions.h"
#include "remote_mirror_rules.h"

#include <saas/library/persqueue/configuration/service/modify_manager/proto/changes.pb.h>
#include <saas/library/persqueue/configuration/service/modify_manager/components.h>

namespace NSaasLB {

    class TLogbrokerCluster : public IComponent<TLogbrokerModifyRequests> {
    private:
        class TImpl;

    public:
        TLogbrokerCluster(
            const TString& server,
            const TString& token,
            const std::optional<TString>& remoteMirrorRulesToken = {}
        );
        ~TLogbrokerCluster();

        void AddOrUpdateEntity(const IEntity& entity);
        void RemoveEntity(const IEntity& entity);

        void AddReadRules(const TVector<TReadRule>& readRules);
        void RemoveReadRules(const TVector<TReadRule>& readRules);

        void AddRemoteMirrorRules(const TVector<TRemoteMirrorRule>& rules);
        void RemoveRemoteMirrorRules(const TVector<TRemoteMirrorRule>& rules);

        void AddYtDelivery(const TString& topicPath, const TString& ytDelivery);
        void RemoveYtDelivery(const TString& topicPath, const TString& ytDelivery);

        NLogBroker::DescribePathResult GetDescribed(const TString& path);
        TVector<TString> GetTopics(const TString& path);
        TVector<TString> GetConsumers(const TString& path);
        TVector<TReadRule> GetReadRules(const TString& path);
        TVector<TRemoteMirrorRule> GetRemoteMirrorRules(const TString& path);
        TVector<TString> GetYtDeliveries(const TString& topicPath);

        TTopic GetTopic(const TString& path);
        TConsumer GetConsumer(const TString& path);

        void GrantPermissions(const TString& path, const TVector<EPermission>& permissions, const TString& subject);
        void RevokePermissions(const TString& path, const TVector<EPermission>& permissions, const TString& subject);

        const TLogbrokerModifyRequests& GetChanges() const override;
        void Apply(ui32 changesCount = 0) override;

    private:
        TVector<TString> GetEntityList(const TString& path, const EEntityType entityType);

    private:
        THolder<TImpl> Impl;
    };

}
