#include "resolve_helper.h"

#include <balancer/kernel/dns/async_simple/async_simple_resolver.h>


namespace NSrvKernel {
using namespace NConfig;

namespace NProcessCore {

TResolveHelper::TResolveHelper(TDuration resolveTimeout)
    : ResolveTimeout_(resolveTimeout)
    , Resolver_(MakeHolder<NDns::TAsyncSimpleResolver>(resolveTimeout))
{
}

TResolveHelper::~TResolveHelper() = default;

void TResolveHelper::StartResolve(IConfig& parser, int family) {
    if (ResolveStart_ != TInstant()) {
        Y_ASSERT(false); // already started
        return;
    }

    ParseMap(&parser, [&](const auto& key, auto* value) {
        if (key == "ipdispatch") {
            ParseIpDispatch(*value->AsSubConfig());
        }
    });

    Resolver_->StartResolve(HostToIp_, family);
    ResolveStart_ = TInstant::Now();
}

void TResolveHelper::WaitForResults() const {
    if (ResolveStart_ == TInstant()) {
        Y_ASSERT(false); // not started yet
        return;
    }

    Y_ASSERT(TInstant::Now() > ResolveStart_);
    const TDuration passed = TInstant::Now() - ResolveStart_;
    Resolver_->WaitForResults(ResolveTimeout_ > passed ? ResolveTimeout_ - passed : TDuration::MilliSeconds(1));
}

void TResolveHelper::ParseIpDispatch(IConfig& parser) {
    ParseMap(&parser, [&](const auto& key, auto* value) {
        if (key != "proxy") {
            ParseIpDispatch(*value->AsSubConfig());
        } else {
            ParseProxy(*value->AsSubConfig());
        }
    });
}

void TResolveHelper::ParseProxy(IConfig& parser) {
    // Check that we have CachedIp for host
    TString host;
    TString ip;
    ParseMap(&parser, [&](const auto& key, auto* value) {
        if (key == "host") {
            Y_ASSERT(host.empty());
            host = value->AsString();
        } else if (key == "cached_ip") {
            Y_ASSERT(ip.empty());
            ip = value->AsString();
        }
    });
    Y_ASSERT(!host.empty());
    if (ip.empty() && !host.empty()) {
        HostToIp_.insert({std::move(host), std::move(ip)});
    }
}

}}