#include "snmp_util.hpp"

#include "xyz/openbmc_project/Common/error.hpp"

#include <arpa/inet.h>
#include <netdb.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>

#include <string>

namespace phosphor
{

using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;

ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus,
                                  const std::string& service,
                                  const std::string& objPath)
{
    ObjectValueTree interfaces;

    auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
                                      "org.freedesktop.DBus.ObjectManager",
                                      "GetManagedObjects");

    auto reply = bus.call(method);

    if (reply.is_method_error())
    {
        log<level::ERR>("Failed to get managed objects",
                        entry("PATH=%s", objPath.c_str()));
        elog<InternalFailure>();
    }

    reply.read(interfaces);
    return interfaces;
}

namespace network
{

std::string resolveAddress(const std::string& address)
{
    addrinfo hints{};
    addrinfo* addr = nullptr;

    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags |= AI_CANONNAME;

    auto result = getaddrinfo(address.c_str(), NULL, &hints, &addr);
    if (result)
    {
        log<level::ERR>("getaddrinfo failed",
                        entry("ADDRESS=%s", address.c_str()));
        elog<InternalFailure>();
    }

    AddrPtr addrPtr{addr};
    addr = nullptr;

    char ipaddress[INET6_ADDRSTRLEN]{0};
    result = getnameinfo(addrPtr->ai_addr, addrPtr->ai_addrlen, ipaddress,
                         sizeof(ipaddress), NULL, 0, NI_NUMERICHOST);
    if (result)
    {
        log<level::ERR>("getnameinfo failed",
                        entry("ADDRESS=%s", address.c_str()));
        elog<InternalFailure>();
    }

    unsigned char buf[sizeof(struct in6_addr)];
    int isValid = inet_pton(AF_INET, ipaddress, buf);
    if (isValid < 0)
    {
        log<level::ERR>("Invalid address",
                        entry("ADDRESS=%s", address.c_str()));
        elog<InternalFailure>();
    }
    if (isValid == 0)
    {
        int isValid6 = inet_pton(AF_INET6, ipaddress, buf);
        if (isValid6 < 1)
        {
            log<level::ERR>("Invalid address",
                            entry("ADDRESS=%s", address.c_str()));
            elog<InternalFailure>();
        }
    }

    return ipaddress;
}

namespace snmp
{

static constexpr auto busName = "xyz.openbmc_project.Network.SNMP";
static constexpr auto root = "/xyz/openbmc_project/network/snmp/manager";
static constexpr auto clientIntf = "xyz.openbmc_project.Network.Client";

/** @brief Gets the sdbus object for this process.
 *  @return the bus object.
 */
static auto& getBus()
{
    static auto bus = sdbusplus::bus::new_default();
    return bus;
}

std::vector<std::string> getManagers()
{
    std::vector<std::string> managers;
    auto& bus = getBus();
    auto objTree = phosphor::getManagedObjects(bus, busName, root);
    for (const auto& objIter : objTree)
    {
        try
        {
            auto& intfMap = objIter.second;
            auto& snmpClientProps = intfMap.at(clientIntf);
            auto& address =
                std::get<std::string>(snmpClientProps.at("Address"));
            auto& port = std::get<uint16_t>(snmpClientProps.at("Port"));
            auto ipaddress = phosphor::network::resolveAddress(address);
            auto mgr = std::move(ipaddress);
            if (port > 0)
            {
                mgr += ":";
                mgr += std::to_string(port);
            }
            managers.push_back(mgr);
        }
        catch (const std::exception& e)
        {
            log<level::ERR>(e.what());
        }
    }
    return managers;
}

} // namespace snmp
} // namespace network
} // namespace phosphor
