// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright OpenBMC Authors
#pragma once
#include "dbus_singleton.hpp"
#include "logging.hpp"

#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/basic_endpoint.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <sdbusplus/message.hpp>

#include <charconv>
#include <memory>

namespace async_resolve
{

inline bool endpointFromResolveTuple(const std::vector<uint8_t>& ipAddress,
                                     boost::asio::ip::tcp::endpoint& endpoint)
{
    if (ipAddress.size() == 4) // ipv4 address
    {
        BMCWEB_LOG_DEBUG("ipv4 address");
        boost::asio::ip::address_v4 ipv4Addr(
            {ipAddress[0], ipAddress[1], ipAddress[2], ipAddress[3]});
        endpoint.address(ipv4Addr);
    }
    else if (ipAddress.size() == 16) // ipv6 address
    {
        BMCWEB_LOG_DEBUG("ipv6 address");
        boost::asio::ip::address_v6 ipv6Addr(
            {ipAddress[0], ipAddress[1], ipAddress[2], ipAddress[3],
             ipAddress[4], ipAddress[5], ipAddress[6], ipAddress[7],
             ipAddress[8], ipAddress[9], ipAddress[10], ipAddress[11],
             ipAddress[12], ipAddress[13], ipAddress[14], ipAddress[15]});
        endpoint.address(ipv6Addr);
    }
    else
    {
        BMCWEB_LOG_ERROR("Resolve failed to fetch the IP address");
        return false;
    }
    return true;
}

class Resolver
{
  public:
    // unused io param used to keep interface identical to
    // boost::asio::tcp:::resolver
    explicit Resolver(boost::asio::io_context& /*io*/) {}

    ~Resolver() = default;

    Resolver(const Resolver&) = delete;
    Resolver(Resolver&&) = delete;
    Resolver& operator=(const Resolver&) = delete;
    Resolver& operator=(Resolver&&) = delete;

    using results_type = std::vector<boost::asio::ip::tcp::endpoint>;

    template <typename ResolveHandler>
    // This function is kept using snake case so that it is interoperable with
    // boost::asio::ip::tcp::resolver
    // NOLINTNEXTLINE(readability-identifier-naming)
    void async_resolve(std::string_view host, std::string_view port,
                       ResolveHandler&& handler)
    {
        BMCWEB_LOG_DEBUG("Trying to resolve: {}:{}", host, port);

        uint16_t portNum = 0;

        auto it = std::from_chars(&*port.begin(), &*port.end(), portNum);
        if (it.ec != std::errc())
        {
            BMCWEB_LOG_ERROR("Failed to get the Port");
            handler(std::make_error_code(std::errc::invalid_argument),
                    results_type{});

            return;
        }

        uint64_t flag = 0;
        crow::connections::systemBus->async_method_call(
            [host{std::string(host)}, portNum,
             handler = std::forward<ResolveHandler>(handler)](
                const boost::system::error_code& ec,
                const std::vector<
                    std::tuple<int32_t, int32_t, std::vector<uint8_t>>>& resp,
                const std::string& hostName, const uint64_t flagNum) {
                results_type endpointList;
                if (ec)
                {
                    BMCWEB_LOG_ERROR("Resolve failed: {}", ec.message());
                    handler(ec, endpointList);
                    return;
                }
                BMCWEB_LOG_DEBUG("ResolveHostname returned: {}:{}", hostName,
                                 flagNum);
                // Extract the IP address from the response
                for (const std::tuple<int32_t, int32_t, std::vector<uint8_t>>&
                         resolveList : resp)
                {
                    boost::asio::ip::tcp::endpoint endpoint;
                    endpoint.port(portNum);
                    if (!endpointFromResolveTuple(std::get<2>(resolveList),
                                                  endpoint))
                    {
                        boost::system::error_code ecErr = make_error_code(
                            boost::system::errc::address_not_available);
                        handler(ecErr, endpointList);
                    }
                    BMCWEB_LOG_DEBUG("resolved endpoint is : {}",
                                     endpoint.address().to_string());
                    endpointList.push_back(endpoint);
                }
                // All the resolved data is filled in the endpointList
                handler(ec, endpointList);
            },
            "org.freedesktop.resolve1", "/org/freedesktop/resolve1",
            "org.freedesktop.resolve1.Manager", "ResolveHostname", 0, host,
            AF_UNSPEC, flag);
    }
};

} // namespace async_resolve
