#include "main.hpp"
#include <assert.h>
#include <dlfcn.h>
#include <dirent.h>
#include <unistd.h>

#include <iostream>
#include <tuple>

#include <systemd/sd-bus.h>
#include <systemd/sd-daemon.h>
#include <systemd/sd-event.h>

#include <host-ipmid/ipmid-api.h>
#include "comm_module.hpp"
#include "command_table.hpp"
#include "message.hpp"
#include "message_handler.hpp"
#include "provider_registration.hpp"
#include "sessions_manager.hpp"
#include "socket_channel.hpp"

// Tuple of Global Singletons
session::Manager manager;
command::Table table;
std::tuple<session::Manager&, command::Table&> singletonPool(manager, table);

sd_bus* bus = nullptr;
FILE* ipmidbus = nullptr;
unsigned short g_sel_reserve = 0xFFFF;
sd_bus_slot* ipmid_slot = nullptr;

/*
 * @brief Required by apphandler IPMI Provider Library
 */
sd_bus* ipmid_get_sd_bus_connection()
{
    return bus;
}

/*
 * @brief Required by apphandler IPMI Provider Library
 */
unsigned short get_sel_reserve_id()
{
    return g_sel_reserve;
}

/*
 * TODO : The plan is to refactor the event loop to support adding multiple
 * file descriptors and event handlers for implementing the Serial Over LAN.
 *
 * A class would abstract the features provided by the sd_event_loop
 */

namespace eventloop
{

static int io_handler(sd_event_source* es, int fd, uint32_t revents,
                      void* userdata)
{
    std::shared_ptr<udpsocket::Channel> channelPtr;
    struct timeval timeout;
    timeout.tv_sec = SELECT_CALL_TIMEOUT;
    timeout.tv_usec = 0;

    channelPtr.reset(new udpsocket::Channel(fd, timeout));

    // Initialize the Message Handler with the socket channel
    message::Handler msgHandler(channelPtr);

    // Read the incoming IPMI packet
    std::unique_ptr<message::Message> inMessage;
    try
    {
        inMessage = msgHandler.receive();
    }
    catch (std::exception& e)
    {
        std::cerr << "Reading & Parsing the incoming IPMI message failed\n";
        std::cerr << e.what() << "\n";
        return 0;
    }

    // Execute the Command
    auto outMessage = msgHandler.executeCommand(*(inMessage.get()));
    if (outMessage == nullptr)
    {
        std::cerr << "Execution of IPMI command failed\n";
        return 0;
    }

    // Send the response IPMI Message
    msgHandler.send(*(outMessage.get()));

    return 0;
}

int startEventLoop()
{
    struct sockaddr_in6 in {};

    sd_event_source* event_source = nullptr;
    sd_event* event = nullptr;
    int fd = -1, r;
    sigset_t ss;

    r = sd_event_default(&event);
    if (r < 0)
    {
        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, nullptr) < 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(event, nullptr, SIGTERM, nullptr, nullptr);
    if (r < 0)
    {
        goto finish;
    }

    r = sd_event_add_signal(event, nullptr, SIGINT, nullptr, nullptr);
    if (r < 0)
    {
        goto finish;
    }

    fd = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
    if (fd < 0)
    {
        r = -errno;
        goto finish;
    }

    in.sin6_family = AF_INET6;
    in.sin6_port = htons(IPMI_STD_PORT);

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

    r = sd_event_add_io(event, &event_source, fd, EPOLLIN, io_handler, nullptr);
    if (r < 0)
    {
        goto finish;
    }

    r = sd_event_loop(event);

finish:
    event_source = sd_event_source_unref(event_source);
    event = sd_event_unref(event);

    if (fd >= 0)
    {
        (void) close(fd);
    }

    if (r < 0)
    {
        fprintf(stderr, "Failure: %s\n", strerror(-r));
    }

    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

} // namespace eventloop

int main(int i_argc, char* i_argv[])
{

    /*
     * Required by apphandler IPMI Provider Library for logging.
     */
    ipmidbus =  fopen("/dev/null", "w");

    // Connect to system bus
    auto rc = sd_bus_open_system(&bus);
    if (rc < 0)
    {
        std::cerr << "Failed to connect to system bus:" << strerror(-rc) <<"\n";
        goto finish;
    }

    // Register all the IPMI provider libraries applicable for net-ipmid
    provider::registerCallbackHandlers(NET_IPMID_LIB_PATH);

    // Register the phosphor-net-ipmid session setup commands
    command::sessionSetupCommands();

    // Start Event Loop
    return eventloop::startEventLoop();

finish:
    sd_bus_unref(bus);

    return 0;
}
