#pragma once

#include "pinger.h"

#include <balancer/kernel/balancing/backend.h>
#include <balancer/kernel/pinger/pinger_backend_manager.h>
#include <balancer/kernel/pinger/pinger_backend_group_manager.h>
#include <balancer/kernel/coro/coroutine.h>
#include <balancer/kernel/http/parser/http.h>
#include <balancer/kernel/pinger/common/backend_pinger.h>

namespace NSrvKernel {
class IWorkerCtl;

class IPingableV2 : public IPingable {
public:
    virtual void SetWeightFromPing(double value, bool valueFromBackend) noexcept = 0;
    virtual double OriginalWeight() const noexcept = 0;
    virtual void SetDegraded(bool value) noexcept = 0;
    virtual void SetGroupName(TString groupName) noexcept = 0;
};

class TPingerV2 final: public IBackendPinger {
public:
    TPingerV2(IPingableV2& backend, const TPingerConfig& config, IWorkerCtl& process, bool useDynamicWeight = false,
              bool useDegradationNotification = false, bool useBackendsGrouping = false);

    TDuration Delay() const override {
        return Config_.Delay;
    }

    void ProcessPingResult(const TBackendStatus& status) override;
    TBackendStatus BackendStatusFromResponse(TResponse& response, double defaultWeight) noexcept;
    TBackendStatus Ping() noexcept override;
    void LoadCounters(TPingerStatsCounters* counters) noexcept override;

private:
    IPingableV2& Backend_;
    const TPingerConfig& Config_;
    IWorkerCtl& Process_;
    bool UseDynamicWeight_ = false;
    bool UseDegradationNotification_ = false;
    bool UseBackendsGrouping_ = false;

    TPingerStatsCounters* Counters_ = nullptr;
};

}
