#pragma once

#include <saas/library/searchmap/searchmap.h>

#include <library/cpp/json/json_value.h>

namespace NSearchProxy {
    struct TBackendReply {
        NSearchMapParser::TSearchMapHost Host;
        TString Data;
        bool Failed = false;
    };
    using TBackendReplies = TVector<TBackendReply>;

    class TBroadcastContext: public TAtomicRefCount<TBroadcastContext> {
    public:
        const TString Service;
        const TString Request;

        TBackendReplies Replies;
        ui64 Requested = 0;
        ui64 Failed = 0;

    public:
        TBroadcastContext(const TString& service, const TString& request)
            : Service(service)
            , Request(request)
        {
        }

        inline bool AnswerIsComplete() const {
            return Failed == 0;
        }
        inline bool Empty() const {
            return Requested == 0;
        }
    };
    using TBroadcastContextPtr = TIntrusivePtr<TBroadcastContext>;

    class TBroadcaster {
    public:
        TBroadcaster(const NSearchMapParser::TSearchMap& searchMap)
            : SearchMap(searchMap)
        {
        }

        TBroadcastContextPtr Broadcast(const TString& service, const TString& request, const TDuration timeout) const;
        void Broadcast(
            const TString& service,
            const TString& request,
            const TDuration timeout,
            std::function<void(const TBackendReply&)> f
        ) const;

    private:
        const NSearchMapParser::TSearchMap& SearchMap;
    };

    NJson::TJsonValue ToJson(const TBackendReply& reply);
}
