#pragma once

#include "host.h"
#include <saas/protos/cluster.pb.h>
#include <library/cpp/json/writer/json_value.h>
#include <util/generic/algorithm.h>
#include <util/generic/set.h>
#include <util/generic/vector.h>

namespace NSearchMapParser {

    class ISlotsPool {
    public:
        virtual TVector<TSearchMapHost> GetSlots() const = 0;
        virtual ~ISlotsPool() {}
    public:
        ui32 Size() const;
        bool SlotExists(const TString& slotName) const;
        bool GetHostBySlot(const TString& name, TSearchMapHost& result) const;
        TSet<TString> GetSlotDescriptionSet() const;
    };

    class IUsedSlotsPool : public ISlotsPool {
    private:
        virtual TVector<TSearchMapHost> GetSlots() const override {
            return GetUsedSlots();
        }

    public:
        virtual TVector<TSearchMapHost> GetUsedSlots() const = 0;
    };

    class TSlotsPool: public ISlotsPool {
    public:
        TVector<TSearchMapHost> Hosts;
        TVector<TSearchMapHost> EndPointSets;

    public:
        virtual TVector<TSearchMapHost> GetSlots() const override;
        TVector<TSearchMapHost> GetEndPointSets() const;

        TVector<TSearchMapHost>& GetMutableSlots();
        TVector<TSearchMapHost>& GetMutableEndPointSets();

        bool EndpointSetExists(const TString& eSetName) const;

        void Clear();
        void Parse(const TVector<TString>& slots);
        bool Add(const TSearchMapHost& host);
        NJson::TJsonValue Serialize() const;
        bool DeserializeFromString(const TString& data);
        bool DeserializeFromJson(const NJson::TJsonValue& data);
        bool Deserialize(const NSaasProto::TSlotsPool& pool);

        NSaasProto::TSlotsPool SerializeToProto() const;

        template<class C>
        void Sort(C sorter) {
            ::Sort(Hosts.begin(), Hosts.end(), sorter);
            ::Sort(EndPointSets.begin(), EndPointSets.end(), sorter);
        }
    };

}
