#include "dns_helper.h"

#include <balancer/kernel/dns/its_switch.h>
#include <balancer/kernel/thread/threadedqueue.h>


using namespace NConfig;
using namespace NSrvKernel;

namespace NSrvKernel::NDns {

NDns::TResolverConfig MakeDnsConfig(const THelperConfig& config, bool useAsync)
{
    return { config.Timeout,
             config.Ttl,
             config.ErrorTtl,
             config.Ip,
             config.Port,
             config.SwitchFile,
             config.SwitchCheckTimeout,
             useAsync };
}

TString THelper::CreateDnsResolver(TContExecutor* executor,
                                   TSharedFiles* sharedFiles,
                                   const THelperConfig& config,
                                   NDns::TStatsCounters* counters,
                                   bool useAsync,
                                   TThreadedQueue* queue)
{
    Y_ASSERT(counters);
    const auto dnsConfig = MakeDnsConfig(config, useAsync);
    THolder<NDns::IResolver> resolver = NDns::MakeItsSwitchResolver(
            executor, *counters, sharedFiles, dnsConfig, queue);

    ResetResolver(std::move(resolver));

    CreateResetDnsCacheCoro(executor, config.ResetCacheFile, sharedFiles);

    return dnsConfig.ToString();
}

void THelper::ResetDnsCache() noexcept
{
    Resolver().ResetCache();
}

void THelper::CreateResetDnsCacheCoro(TContExecutor* executor, const TString& resetDnsCacheFile, TSharedFiles* sharedFiles)
{
    if (resetDnsCacheFile.empty())
        return;

    Y_VERIFY(sharedFiles);
    ResetDnsCacheFileChecker_ = sharedFiles->FileChecker(resetDnsCacheFile, TDuration::Seconds(1));
    ResetDnsCacheCont_ = TCoroutine{ECoroType::Service, "reset_dns_cache_cont", executor, [this, executor] {
        auto* const cont = executor->Running();
        bool hasResetDnsCacheFile = false;
        while (!cont->Cancelled()) {
            bool prev = hasResetDnsCacheFile;
            bool current = ResetDnsCacheFileChecker_.Exists();
            if (prev != current) {
                hasResetDnsCacheFile = current;
                if (current) {
                    ResetDnsCache();
                }
            }
            cont->SleepT(TDuration::Seconds(1));
        }
    }
    };
}
}
