#include "types.hpp"
#include "rtnetlink_server.hpp"
#include "network_manager.hpp"
#include "mock_syscall.hpp"
#include "timer.hpp"
#include "types.hpp"


#include <gtest/gtest.h>
#include <sdbusplus/bus.hpp>

#include <net/if.h>
#include <linux/rtnetlink.h>

namespace phosphor
{

namespace network
{
sdbusplus::bus::bus bus(sdbusplus::bus::new_default());
std::unique_ptr<Manager> manager = nullptr;
std::unique_ptr<Timer> refreshObjectTimer = nullptr;
std::unique_ptr<Timer> restartTimer = nullptr;
EventPtr eventPtr = nullptr;

/** @brief refresh the network objects. */
void refreshObjects()
{

    if (manager)
    {
        manager->createChildObjects();
    }
}

void initializeTimers()
{
    std::function<void()> refreshFunc(
        std::bind(&refreshObjects));

    refreshObjectTimer =
        std::make_unique<Timer>(refreshFunc);

}

class TestRtNetlink : public testing::Test
{

    public:
        std::string confDir;
        phosphor::Descriptor smartSock;



        TestRtNetlink()
        {
            manager =
                std::make_unique<Manager>(bus,
                        "/xyz/openbmc_test/bcd",
                        "/tmp");
            sd_event* events;
            sd_event_default(&events);
            eventPtr.reset(events);
            events = nullptr;
            setConfDir();
            initializeTimers();
            createNetLinkSocket();
            bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
            rtnetlink::Server svr(eventPtr, smartSock);
        }

        ~TestRtNetlink()
        {
            if (confDir.empty())
            {
                fs::remove_all(confDir);
            }
        }

        void setConfDir()
        {
            char tmp[] = "/tmp/NetworkManager.XXXXXX";
            confDir = mkdtemp(tmp);
            manager->setConfDir(confDir);
        }

        bool isInterfaceAdded(std::string intf)
        {
            return manager->interfaces.find(intf) != manager->interfaces.end()?
                   true :
                   false;
        }

        void createNetLinkSocket()
        {
            //RtnetLink socket
            auto fd = socket(PF_NETLINK, SOCK_RAW | SOCK_NONBLOCK,
                NETLINK_ROUTE);
            smartSock.set(fd);
        }
};


TEST_F(TestRtNetlink, WithSingleInterface)
{
    using namespace std::chrono;
    // Adds the following ip in the getifaddrs list.
    mock_addIP("igb5", "127.0.0.1", "255.255.255.128",
               IFF_UP | IFF_RUNNING);
    constexpr auto BUFSIZE = 4096;
    std::array<char, BUFSIZE> msgBuf = {0};

    // point the header and the msg structure pointers into the buffer.
    auto nlMsg = reinterpret_cast<nlmsghdr*>(msgBuf.data());
    // Length of message
    nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(rtmsg));
    nlMsg->nlmsg_type = RTM_GETADDR;
    nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
    nlMsg->nlmsg_seq = 0;
    nlMsg->nlmsg_pid = getpid();

    EXPECT_EQ(false, isInterfaceAdded("igb5"));
    // Send the request
    send(smartSock(), nlMsg, nlMsg->nlmsg_len, 0);

    int i = 3;
    while (i--)
    {
        //wait for timer to expire
        std::this_thread::sleep_for(
            std::chrono::milliseconds(refreshTimeout));
        sd_event_run(eventPtr.get(), 10);
    };

    EXPECT_EQ(true, isInterfaceAdded("igb5"));
}

}// namespce network
}// namespace phosphor
