#include "request_utils.h"

#include <balancer/kernel/dns/resolver_face.h>

#include <library/cpp/uri/uri.h>

namespace NHttp::NUtils {
TExpected<TRequest, TError> BuildRequest(TStringBuf url) {
    NUri::TUri uri;
    Y_VERIFY(uri.Parse(url, NUri::TUri::ESets::FeaturesRecommended) == NUri::TState::ParsedOK);
    NHttp::TRequest request;

    ui16 port;
    if (uri.GetScheme() == NUri::TScheme::SchemeHTTPS) {
        port = 443;
        request.Secure = true;
    } else {
        Y_VERIFY(uri.GetScheme() == NUri::TScheme::SchemeHTTP ||
                 uri.GetScheme() == NUri::TScheme::SchemeEmpty);
        port = 80;
    }

    if (uri.GetField(NUri::TField::FieldPort)) {
        port = uri.GetPort();
    }

    auto host = TString{uri.GetHost()};
    if (uri.GetField(NUri::TField::FieldPort)) {
        host += ":" + ToString(uri.GetPort());
    }

    request.Headers.AddHeader("Host", host);
    request.Path = uri.GetField(NUri::TField::FieldPath);
    request.Query.Scan(uri.GetField(NUri::TField::FieldQuery));

    auto result = NSrvKernel::NDns::TSimpleResolver::Resolve(NSrvKernel::NDns::TResolveInfo{.Host = TString{uri.GetHost()}, .Port = port});
    NSrvKernel::TSockAddrInfo addrs;
    if (auto error = result.AssignTo(addrs)) {
        return TError{error->what()};
    }

    Y_VERIFY(!addrs.Addresses.empty());

    request.Endpoint = TResolvedEndpoint {
        .Ip = addrs.Addresses[0].Ip().ToString(),
        .Port = addrs.Addresses[0].Port()
    };

    return request;
}
}
