#include <libpdbg.h>

#include <attn/attn_main.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <cli.hpp>
#include <listener.hpp>

/** @brief openpower-hw-diags message queue name */
static constexpr const char* mq_listener = "openpower-hw-diags-mq";

/** @brief maximum length of command line parameter */
static constexpr int max_command_len = 25;

/** @brief end of command line args message */
static const char* msg_send_end = "999999999999999";

/**
 * @brief Start a thread to monitor the attention GPIO
 *
 * @param i_config Attention handler configuration object
 */
void* threadGpioMon(void* i_config)
{
    // Configure and start attention monitor
    attn::attnDaemon((attn::Config*)i_config);

    pthread_exit(NULL);
}

/** @brief Start a thread to listen for attention handler messages */
void* threadListener(void* i_params)
{
    using namespace boost::interprocess;

    // remove listener message queue if exists (does not throw)
    message_queue::remove(mq_listener);

    // thread handle for gpio monitor
    pthread_t ptidGpio;

    // status of gpio monitor
    bool gpioMonEnabled = false;

    // create config
    attn::Config attnConfig;

    // This is the main listener loop. All the above code will be executed
    // only once. All other communtication with the attention handler will
    // originate from here via the message queue.
    do
    {
        // vector to hold messages sent to listener
        std::vector<std::string> messages;
        // we will catch any exceptions from thread library
        try
        {
            // create new message queue or open existing
            message_queue mq(open_or_create, mq_listener, 1, max_command_len);

            // message queue parameters
            char buffer[max_command_len + 1];
            size_t recvd_size;
            unsigned int priority;

            // We will continue receiving messages until we receive
            // a msg_send_end message to indicate all command line parameters
            // have been sent.
            do
            {
                // wait for a message to arrive
                mq.receive((void*)&buffer, max_command_len, recvd_size,
                           priority);

                // null terminate message and store
                buffer[recvd_size] = '\0';
                messages.push_back(buffer);

            } while (buffer != std::string(msg_send_end));

            messages.pop_back(); // remove msg_send_end message

            // convert messages to command line arguments
            std::vector<char*> argv;

            std::transform(messages.begin(), messages.end(),
                           std::back_inserter(argv), (char*)data());

            int argc = argv.size();
            argv.push_back(nullptr);

            // stop attention handler daemon?
            if (true == getCliOption(argv.data(), argv.data() + argc, "--stop"))
            {
                message_queue::remove(mq_listener);
                break;
            }

            // parse config options
            parseConfig(argv.data(), argv.data() + argc, &attnConfig);

            // start attention handler daemon?
            if (true ==
                getCliOption(argv.data(), argv.data() + argc, "--start"))
            {
                if (false == gpioMonEnabled)
                {
                    if (0 == pthread_create(&ptidGpio, NULL, &threadGpioMon,
                                            &attnConfig))
                    {
                        gpioMonEnabled = true;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }

        catch (interprocess_exception& e)
        {
            break;
        }
    } while (1);

    // stop the gpio monitor if running
    if (true == gpioMonEnabled)
    {
        pthread_cancel(ptidGpio);
    }

    pthread_exit(NULL);
}

/** @brief Send command line to a threadi */
int sendCmdLine(int i_argc, char** i_argv)
{
    int count = 0; // number of arguments sent

    using namespace boost::interprocess;

    try
    {
        message_queue mq(open_only, mq_listener);

        while (count < i_argc)
        {
            mq.send(i_argv[count], strlen(i_argv[count]), 0);
            count++;
        }
        // indicate to listener last cmdline arg was sent
        mq.send(msg_send_end, strlen(msg_send_end), 0);
    }
    catch (interprocess_exception& e)
    {
        count = 0; // assume no arguments sent
    }
    return count;
}

/** @brief See if the listener thread message queue exists */
bool listenerMqExists()
{
    using namespace boost::interprocess;

    try
    {
        message_queue mq(open_only, mq_listener);
        return true;
    }
    catch (interprocess_exception& e)
    {
        return false;
    }
}
