#pragma once

#include <balancer/kernel/process/base_process.h>
#include <balancer/kernel/process/master_main.h>
#include <balancer/kernel/process/messages.h>

#include <balancer/kernel/coro/coroutine.h>
#include <balancer/kernel/ctl/ctl.h>

#include <balancer/kernel/pinger/pinger_backend_manager.h>
#include <balancer/kernel/ctl/children_process_common.h>
#include <balancer/kernel/process/children_common/process_stat.h>
#include <balancer/kernel/process_common/main_options.h>

#include <util/thread/factory.h>

namespace NSrvKernel {
namespace NDns {
class THelper;
}

namespace NProcessCore {
class TMainStats;

    class TPingerProcess
        : public TBaseProcess
    {
    public:
        void Execute() override;
        void RecvLoop();
        void Stop();

        TSharedFiles* SharedFiles() noexcept override;
        TThreadedQueue* ThreadedQueue(const TString& name) noexcept override;
        TPingerManager& SharedPingerManager() noexcept override;
        TLog* GetLog(const TString&) override;
        TLog* GetDynamicBalancingLog() override;
        NProcessCore::TChildProcessType WorkerType() const noexcept override;
        NDns::IResolver& Resolver() noexcept final;
        TContExecutor& Executor() const noexcept override {
            return Executor_->Executor();
        }

        void DumpSharedFiles(NJson::TJsonWriter&) override {}
        void AddGracefulShutdownHandler(IGracefulShutdownHandler*, bool) override {}

        void DoDispose() noexcept override;

        TPingerProcess(TMainTask& task, const TMainOptions& options, TW2WChannel<TM2CMessage>& m2cChannel);
        ~TPingerProcess();

    public:
        THolder<TOwnExecutor> Executor_;

    private:
        THolder<TMainStats> MainStats_;
        THolder<TWorkerCpuStat> WorkerCpuStat_;
        THolder<TPingerManager> PingerStatsManager_;
        TW2WChannel<TM2CMessage>& M2CChannel_;
        THolder<NDns::TStatsCounters> DnsCounters_;
        THolder<TSharedFiles> SharedFiles_;

        IThreadFactory* ThreadPool_ = SystemThreadFactory();
        TThreadedQueueList ThreadedQueueList_;

        // small pingers use modules that use logs inside
        // so we need ability to reopen logs
        // otherwise nanny will kill the pinger process
        TContextSafeLog<TSystemLog> PingerLog_;

        TCoroutine CpuMeasureCoroutine_;
        TCoroutine RecvLoopTask_;
        THolder<NDns::THelper> DnsHelper_;
    };
}}
