#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <lmdb.h>
#include <unistd.h>
#include <sys/socket.h>
#include <poll.h>

#include <logger.h>
#include <models/controller.h>
#include <database.h>
#include <config.h>
#include <discovery.h>
#include <enums.h>

/**
 * @brief The main function
 *
 * @param argc UNUSED
 * @param argv UNUSED
 *
 * @return Statuscode to indicate success (0) or failure (!0)
 */
int
main(int argc, char** argv)
{
    (void)argc;
    (void)argv;

    MDB_env *mdb_env;
    database_setup(&mdb_env);

    controller *this_cntrlr = controller_load(mdb_env);
    controller_save(this_cntrlr, mdb_env);

    int fd_discovery = discovery_socket_open(this_cntrlr->discovery_port);

    struct pollfd fds[2];
    int timeout_msecs = ACCEPT_TIMEOUT_MSECONDS;
    int ret;
    int i;
    int fd_count = 0;

    /* Open STREAMS device. */
    fds[POLL_FGS_DISCOVERY].fd = fd_discovery;
    fds[POLL_FGS_DISCOVERY].events = POLLIN;
    LOG_DEBUG("setup fd_discovery as %i on index %i", fd_discovery, fd_count);
    fd_count++;

    while(1)
    {
        ret = poll(fds, fd_count, timeout_msecs);

        if(ret == 0)
        {
            LOG_TRACE("idle loop");
        }
        if(ret > 0)
        {
            /* An event on one of the fds has occurred. */
            for(i = 0; i < fd_count; i++) {
                if(fds[i].revents & POLLIN)
                {
                    /* Priority data may be read on device number i. */
                    LOG_DEBUG("fd %i may read data", fds[i].fd);
                    switch(i)
                    {
                        case POLL_FGS_DISCOVERY:
                            discovery_handle_discover(fd_discovery, this_cntrlr);
                    }
                }
                if(fds[i].revents & POLLHUP)
                {
                    /* A hangup has occurred on device number i. */
                    LOG_DEBUG("fd %i got closed", fds[i].fd);
                }
            }
        }
    }

    close(fd_discovery);

    mdb_env_close(mdb_env);

    return 0;
}