#include "rtnetlink_server.hpp"

#include "types.hpp"
#include "util.hpp"

#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <systemd/sd-daemon.h>
#include <unistd.h>

#include <memory>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

namespace phosphor
{
namespace network
{

extern std::unique_ptr<Timer> refreshObjectTimer;

namespace rtnetlink
{

/* Call Back for the sd event loop */
static int eventHandler(sd_event_source* es, int fd, uint32_t revents,
                        void* userdata)
{
    char buffer[phosphor::network::rtnetlink::BUFSIZE]{};
    int len{};

    auto netLinkHeader = reinterpret_cast<struct nlmsghdr*>(buffer);
    while ((len = recv(fd, netLinkHeader, phosphor::network::rtnetlink::BUFSIZE,
                       0)) > 0)
    {
        for (; (NLMSG_OK(netLinkHeader, len)) &&
               (netLinkHeader->nlmsg_type != NLMSG_DONE);
             netLinkHeader = NLMSG_NEXT(netLinkHeader, len))
        {
            if (netLinkHeader->nlmsg_type == RTM_NEWADDR ||
                netLinkHeader->nlmsg_type == RTM_DELADDR)
            {
                // starting the timer here to make sure that we don't want
                // create the child objects multiple times.
                if (refreshObjectTimer->hasExpired())
                {
                    // if start timer throws exception then let the application
                    // crash
                    refreshObjectTimer->restartOnce(refreshTimeout);
                } // end if
            }     // end if

        } // end for

    } // end while

    return 0;
}

Server::Server(EventPtr& eventPtr, const phosphor::Descriptor& smartSock)
{
    using namespace phosphor::logging;
    using InternalFailure =
        sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
    struct sockaddr_nl addr
    {
    };
    int r{};

    sigset_t ss{};
    // check that the given socket is valid or not.
    if (smartSock() < 0)
    {
        r = -EBADF;
        goto finish;
    }

    if (sigemptyset(&ss) < 0 || sigaddset(&ss, SIGTERM) < 0 ||
        sigaddset(&ss, SIGINT) < 0)
    {
        r = -errno;
        goto finish;
    }
    /* Block SIGTERM first, so that the event loop can handle it */
    if (sigprocmask(SIG_BLOCK, &ss, NULL) < 0)
    {
        r = -errno;
        goto finish;
    }

    /* Let's make use of the default handler and "floating"
       reference features of sd_event_add_signal() */

    r = sd_event_add_signal(eventPtr.get(), NULL, SIGTERM, NULL, NULL);
    if (r < 0)
    {
        goto finish;
    }

    r = sd_event_add_signal(eventPtr.get(), NULL, SIGINT, NULL, NULL);
    if (r < 0)
    {
        goto finish;
    }

    memset(&addr, 0, sizeof(addr));
    addr.nl_family = AF_NETLINK;
    addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;

    if (bind(smartSock(), (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
        r = -errno;
        goto finish;
    }

    r = sd_event_add_io(eventPtr.get(), nullptr, smartSock(), EPOLLIN,
                        eventHandler, nullptr);
    if (r < 0)
    {
        goto finish;
    }

finish:

    if (r < 0)
    {
        log<level::ERR>("Failure Occurred in starting of server:",
                        entry("ERRNO=%d", errno));
        elog<InternalFailure>();
    }
}

} // namespace rtnetlink
} // namespace network
} // namespace phosphor
