#pragma once

#include <util/string/vector.h>
#include <util/generic/hash_set.h>

#include <logbroker/public/api/grpc/config_manager.grpc.pb.h>

namespace NSaasLB {

    enum class EPermission {
        ReadTopic,
        WriteTopic,
        ReadAsConsumer,
        ModifyPermissions,
        CreateResources,
        ModifyResources,
        ListResources,
        CreateReadRules,
        DescribeResources
    };

    class TPermissionStorage {
    private:
        using TPermissionSet = THashSet<EPermission>;

    public:
        std::optional<NLogBroker::SingleModifyRequest> Grant(
            const TString& path,
            const TString& subject,
            const TVector<EPermission>& permissions
        );
        std::optional<NLogBroker::SingleModifyRequest> Revoke(
            const TString& path,
            const TString& subject,
            const TVector<EPermission>& permissions
        );

        bool Has(const TString& path, const TString& subject, EPermission permission) const;
        NLogBroker::SingleModifyRequest GetGrantCommand(
            const TString& path,
            const TString& subject,
            const TVector<EPermission>& permissions
        ) const;
        NLogBroker::SingleModifyRequest GetRevokeCommand(
            const TString& path,
            const TString& subject,
            const TVector<EPermission>& permissions
        ) const;

        template<class TProtoEntry>
        void Load(const TString& path, const TProtoEntry& entry) {
            for (auto&& permission : entry.permissions()) {
                auto& subjectPermissions = Permissions[path][permission.subject()];
                for (auto p : permission.permission_names()) {
                    subjectPermissions.insert(FromString<EPermission>(p));
                }
            }
        }

    private:
        THashMap<TString, THashMap<TString, TPermissionSet>> Permissions;
    };

}
