#pragma once

#include <balancer/kernel/stats/manager.h>

namespace {
    static TVector<ui64> DnsResolveIntervals = {
        0,
        1000,
        5000,
        10000,
        25000,
        50000,
        75000,
        100000,
        125000,
        150000,
        175000,
        200000,
        250000,
        500000,
        750000,
        1000000,
        2500000,
        5000000,
        7500000,
        10000000,
        25000000
    };
}

namespace NSrvKernel::NDns {

struct TStatsCounters {
    TStatsCounters(TSharedStatsManager& statsManager, const TString& processName)
        : DnsResolve(statsManager.MakeCounter(TString::Join(processName, "-dns_resolve")).Build())
        , DnsNoDataResult(statsManager.MakeCounter(TString::Join(processName, "-dns_resolve_no_data")).Build())
        , DnsNumericSyncResolve(statsManager.MakeCounter(TString::Join(processName, "-dns_numeric_sync_resolve")).Build())
        , DnsCacheResolve(statsManager.MakeCounter(TString::Join(processName, "-dns_cached_resolve")).Build())
        , DnsResolveTime(statsManager.MakeHistogram(TString::Join(processName, "-dns_resolve_time"), DnsResolveIntervals).Scale(1e6).Build())
        , DnsResolveTimeout(statsManager.MakeCounter(TString::Join(processName, "-dns_resolve_timeout_error")).Build())
        , DnsResolveCancel(statsManager.MakeCounter(TString::Join(processName, "-dns_resolve_cancel_error")).Build())
        , DnsGeneralError(statsManager.MakeCounter(TString::Join(processName, "-dns_resolve_general_error")).Build())
        , DnsResetCache(statsManager.MakeCounter(TString::Join(processName, "-dns_reset_cache")).Build())

        , DnsAsyncNoTimeToResolve(statsManager.MakeCounter(TString::Join(processName, "-dns_async_resolve_timeout_error")).Build())
        , DnsAsyncEmptyAddress(statsManager.MakeCounter(TString::Join(processName, "-dns_async_empty_address_error")).Build())
        , DnsAsyncAlreadyNumeric(statsManager.MakeCounter(TString::Join(processName, "-dns_async_already_numeric")).Build())
        , DnsAsyncResolve(statsManager.MakeCounter(TString::Join(processName, "-dns_async_resolve")).Build())
        , DnsAsyncNoDataResult(statsManager.MakeCounter(TString::Join(processName, "-dns_async_resolve_no_data")).Build())
        , DnsAsyncNxdomain(statsManager.MakeCounter(TString::Join(processName, "-dns_async_resolve_nxdomain")).Build())
        , DnsAsyncResolveError(statsManager.MakeCounter(TString::Join(processName, "-dns_async_resolve_general_error")).Build())
        , DnsAsyncCacheResolve(statsManager.MakeCounter(TString::Join(processName, "-dns_async_cached_resolve")).Build())
        , DnsAsyncCacheError(statsManager.MakeCounter(TString::Join(processName, "-dns_async_cached_error")).Build())
        , DnsAsyncResolveTime(statsManager.MakeHistogram(TString::Join(processName, "-dns_async_resolve_time"), DnsResolveIntervals).Scale(1e6).Build())
        , DnsAsyncResetCache(statsManager.MakeCounter(TString::Join(processName, "-dns_async_reset_cache")).Build())
    {}

    TStatsCounters(TStatsCounters& statsCounters, size_t workerId)
        : DnsResolve(statsCounters.DnsResolve, workerId)
        , DnsNoDataResult(statsCounters.DnsNoDataResult, workerId)
        , DnsNumericSyncResolve(statsCounters.DnsNumericSyncResolve, workerId)
        , DnsCacheResolve(statsCounters.DnsCacheResolve, workerId)
        , DnsResolveTime(statsCounters.DnsResolveTime, workerId)
        , DnsResolveTimeout(statsCounters.DnsResolveTimeout, workerId)
        , DnsResolveCancel(statsCounters.DnsResolveCancel, workerId)
        , DnsGeneralError(statsCounters.DnsGeneralError, workerId)
        , DnsResetCache(statsCounters.DnsResetCache, workerId)

        , DnsAsyncNoTimeToResolve(statsCounters.DnsAsyncNoTimeToResolve, workerId)
        , DnsAsyncEmptyAddress(statsCounters.DnsAsyncEmptyAddress, workerId)
        , DnsAsyncAlreadyNumeric(statsCounters.DnsAsyncAlreadyNumeric, workerId)
        , DnsAsyncResolve(statsCounters.DnsAsyncResolve, workerId)
        , DnsAsyncNoDataResult(statsCounters.DnsAsyncNoDataResult, workerId)
        , DnsAsyncNxdomain(statsCounters.DnsAsyncNxdomain, workerId)
        , DnsAsyncResolveError(statsCounters.DnsAsyncResolveError, workerId)
        , DnsAsyncCacheResolve(statsCounters.DnsAsyncCacheResolve, workerId)
        , DnsAsyncCacheError(statsCounters.DnsAsyncCacheError, workerId)
        , DnsAsyncResolveTime(statsCounters.DnsAsyncResolveTime, workerId)
        , DnsAsyncResetCache(statsCounters.DnsAsyncResetCache, workerId)
    {}

    TSharedCounter DnsResolve;
    TSharedCounter DnsNoDataResult;
    TSharedCounter DnsNumericSyncResolve;
    TSharedCounter DnsCacheResolve;
    TSharedHistogram DnsResolveTime;
    TSharedCounter DnsResolveTimeout;
    TSharedCounter DnsResolveCancel;
    TSharedCounter DnsGeneralError;
    TSharedCounter DnsResetCache;

    TSharedCounter DnsAsyncNoTimeToResolve;
    TSharedCounter DnsAsyncEmptyAddress;
    TSharedCounter DnsAsyncAlreadyNumeric;
    TSharedCounter DnsAsyncResolve;
    TSharedCounter DnsAsyncNoDataResult;
    TSharedCounter DnsAsyncNxdomain;
    TSharedCounter DnsAsyncResolveError;
    TSharedCounter DnsAsyncCacheResolve;
    TSharedCounter DnsAsyncCacheError;
    TSharedHistogram DnsAsyncResolveTime;
    TSharedCounter DnsAsyncResetCache;
};

}
