#include <EventsIo.h>
#include <cstring>

extern "C"
{
    #include <errno.h>
}

// epoll_event datastructure slot indices
const int EventsIo::EVENTS_CTL_INDEX = 0;
const int EventsIo::SIG_CTL_INDEX    = 1;
const int EventsIo::STDIN_CTL_INDEX  = 2;
// Number of epoll_event datastructure slots
const int EventsIo::CTL_SLOTS_COUNT  = 3;

// @throws std::bad_alloc, std::ios_base::failure
EventsIo::EventsIo(int events_input_fd):
    events_fd(events_input_fd),
    ctl_events(new struct epoll_event[CTL_SLOTS_COUNT]),
    fired_events(new struct epoll_event[CTL_SLOTS_COUNT]),
    signal_buffer(new struct signalfd_siginfo),
    events_buffer(new char[MAX_LINE_LENGTH])
{
    try
    {
        // Zero termios datastructures
        static_cast<void> (std::memset(static_cast<void*> (&orig_termios), 0,
                                       sizeof (orig_termios)));
        static_cast<void> (std::memset(static_cast<void*> (&adjusted_termios), 0,
                                       sizeof (adjusted_termios)));

        // Initialize the poll file descriptor
        poll_fd = epoll_create1(EPOLL_CLOEXEC);
        if (poll_fd == -1)
        {
            throw EventsIoException();
        }

        // Initialize signalfds to enable polling for signals
        // Block the default signal handlers for the same signals
        sigset_t mask;
        checked_int_rc(sigemptyset(&mask));
        checked_int_rc(sigaddset(&mask, SIGTERM));
        checked_int_rc(sigaddset(&mask, SIGHUP));
        checked_int_rc(sigaddset(&mask, SIGINT));
        checked_int_rc(sigaddset(&mask, SIGWINCH));
        checked_int_rc(sigaddset(&mask, SIGCHLD));
        checked_int_rc(sigprocmask(SIG_BLOCK, &mask, nullptr));
        sig_fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
        if (sig_fd == -1)
        {
            throw EventsIoException();
        }

        // Initialize poll event data structures
        static_cast<void> (std::memset(static_cast<void*> (ctl_events.get()), 0,
                                       sizeof (struct epoll_event) * CTL_SLOTS_COUNT));
        static_cast<void> (std::memset(static_cast<void*> (fired_events.get()), 0,
                                       sizeof (struct epoll_event) * CTL_SLOTS_COUNT));

        // Register the epoll() events
        register_poll(events_fd, &(ctl_events[EVENTS_CTL_INDEX]), EPOLLIN);
        register_poll(sig_fd, &(ctl_events[SIG_CTL_INDEX]), EPOLLIN);
        register_poll(stdin_fd, &(ctl_events[STDIN_CTL_INDEX]), EPOLLIN);
    }
    catch (EventsIoException&)
    {
        // Cleanup modifies errno, so the relevant information must be cached
        bool os_call_oom = (errno == ENOMEM);
        cleanup();

        if (os_call_oom)
        {
            throw std::bad_alloc();
        }
        throw;
    }
    catch (std::bad_alloc&)
    {
        cleanup();

        throw;
    }
}

EventsIo::~EventsIo() noexcept
{
    cleanup();
}

// @throws EventsIoException
void EventsIo::register_poll(int fd, struct epoll_event* event_ctl_slot, uint32_t event_mask)
{
    event_ctl_slot->data.fd = fd;
    event_ctl_slot->events = event_mask;
    int rc = epoll_ctl(poll_fd, EPOLL_CTL_ADD, fd, event_ctl_slot);
    if (rc != 0)
    {
        throw EventsIoException();
    }
}

// @throws EventsIoException
EventsIo::event EventsIo::wait_event()
{
    EventsIo::event event_id = EventsIo::event::NONE;

    // If data is available in the buffer, look for event lines
    // This check is turned off by prepare_line() if all the available
    // data has been searched and more data must be read to find another
    // event lines
    // read_events() turns this check back on if more data was read
    if (data_pending)
    {
        if (prepare_line())
        {
            event_id = EventsIo::event::EVENT_LINE;
        }
    }

    while (event_id == EventsIo::event::NONE)
    {
        if (!pending_events)
        {
            current_event = 0;
            do
            {
                errno = 0;
                event_count = epoll_wait(poll_fd, fired_events.get(), CTL_SLOTS_COUNT, -1);
                if (event_count > 0)
                {
                    pending_events = true;
                }
                else
                if (errno != 0 && errno != EINTR)
                {
                    throw EventsIoException();
                }
            }
            while (!pending_events);
        }

        int fired_fd = fired_events[current_event].data.fd;
        if (fired_fd == events_fd)
        {
            // Events source data available
            if (events_eof)
            {
                throw EventsIoException();
            }

            read_events();
            if (prepare_line())
            {
                event_id = EventsIo::event::EVENT_LINE;
            }
        }
        else
        if (fired_fd == sig_fd)
        {
            // Signal available
            event_id = EventsIo::event::SIGNAL;
        }
        else
        if (fired_fd == stdin_fd)
        {
            // Data available on stdin
            event_id = EventsIo::event::STDIN;
        }
        else
        {
            // Unknown data source ready, this is not supposed to happen
            throw EventsIoException();
        }

        // Select the next event for processing
        ++current_event;
        if (current_event >= event_count)
        {
            pending_events = false;
        }
    }

    return event_id;
}

// @throws EventsIoException
int EventsIo::get_signal()
{
    int signal_id = 0;

    errno = 0;
    ssize_t read_size = 0;
    do
    {
        read_size = read(sig_fd, signal_buffer.get(), sizeof (struct signalfd_siginfo));
        if (read_size == sizeof (struct signalfd_siginfo))
        {
            signal_id = static_cast<int> (signal_buffer->ssi_signo);
        }
        else
        if (read_size == 0)
        {
            throw EventsIoException();
        }
    }
    while (read_size == -1 && errno == EINTR);

    if (read_size == -1)
    {
        throw EventsIoException();
    }

    return signal_id;
}

// @throws EventsIoException
void EventsIo::adjust_terminal()
{
    // Store current terminal settings
    checked_int_rc(tcgetattr(STDIN_FILENO, &orig_termios));
    have_orig_termios = true;
    adjusted_termios = orig_termios;

    // Non-canonical input without echo
    tcflag_t flags_on = ISIG;
    tcflag_t flags_off = ICANON | ECHO | ECHONL;
    adjusted_termios.c_lflag |= flags_on;
    adjusted_termios.c_lflag = (adjusted_termios.c_lflag | flags_off) ^ flags_off;
    checked_int_rc(tcsetattr(STDIN_FILENO, TCSANOW, &adjusted_termios));
}

// @throws EventsIoException
void EventsIo::restore_terminal()
{
    if (have_orig_termios)
    {
        // Restore original terminal settings
        checked_int_rc(tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios));
    }
}

// @throws EventsIoException
void EventsIo::read_events()
{
    // If there is space remaining in the buffer,
    // read data into the buffer.
    // If the buffer is full, it must be compacted or emptied by
    // calls to get_event_line()
    if (events_length < MAX_LINE_LENGTH)
    {
        size_t length = MAX_LINE_LENGTH - events_length;
        int read_count = 0;
        do
        {
            read_count = read(events_fd, &(events_buffer[events_length]), length);
        }
        while (read_count == -1 && errno == EINTR);
        if (read_count == 0)
        {
            events_eof = true;
        }
        else
        if (read_count == -1)
        {
            if (errno != EAGAIN)
            {
                throw EventsIoException();
            }
        }
        else
        {
            // Indicate that more data has been made available and
            // should be checked for complete lines using prepare_line()
            data_pending = true;
            events_length += read_count;
        }
    }
}

std::string* EventsIo::get_event_line()
{
    if (event_line == nullptr)
    {
        if (!data_pending)
        {
            read_events();
        }
        prepare_line();
    }

    line_pending = false;
    return event_line.get();
}

void EventsIo::free_event_line()
{
    event_line = nullptr;
}

// @throws std::bad_alloc, EventsIoException
bool EventsIo::prepare_line()
{
    if (!line_pending)
    {
        if (event_line != nullptr)
        {
            event_line = nullptr;
        }

        bool have_line = false;
        size_t event_end_pos = 0;
        // Check for new complete lines in the buffer
        char* input_data = events_buffer.get();
        for (size_t index = event_begin_pos; index < events_length; ++index)
        {
            if (input_data[index] == '\n')
            {
                have_line = true;
                event_end_pos = index + 1;
                break;
            }
        }

        if (have_line)
        {
            if (discard_line)
            {
                discard_line = false;
            }
            else
            {
                event_line = std::unique_ptr<std::string>(
                    new std::string(&(input_data[event_begin_pos]), event_end_pos - event_begin_pos - 1)
                );
                line_pending = true;
            }
            event_begin_pos = event_end_pos;
        }
        else
        {
            // Indicate that all available data has been searched for event lines
            // and more data needs to be read to find another event line
            data_pending = false;

            if (event_begin_pos > 0)
            {
                // No more lines in the buffer, compact buffer
                size_t src_index = event_begin_pos;
                size_t dst_index = 0;
                while (src_index < events_length)
                {
                    input_data[dst_index] = input_data[src_index];
                    ++src_index;
                    ++dst_index;
                }
                events_length = events_length - event_begin_pos;
                event_begin_pos = 0;
            }
            else
            if (events_length == MAX_LINE_LENGTH)
            {
                // Buffer is full, but no lines were found
                // Too long line, discard input
                event_begin_pos = 0;
                events_length = 0;
                discard_line = true;

                // Currently, a too long line is considered an error
                // If throwing the exception is removed, too long lines
                // will simply be discarded instead
                throw EventsIoException();
            }
        }
    }

    return line_pending;
}

// Throws EventsIoException if rc is not equal to 0
// @throws EventsIoException
void EventsIo::checked_int_rc(int rc) const
{
    if (rc != 0)
    {
        throw EventsIoException();
    }
}

void EventsIo::cleanup() noexcept
{
    if (poll_fd != -1)
    {
        close(poll_fd);
        poll_fd = -1;
    }

    if (events_fd != -1)
    {
        close(events_fd);
        events_fd = -1;
    }

    if (sig_fd != -1)
    {
        close(sig_fd);
        sig_fd = -1;
    }

    // stdin_fd is not closed
}
