#include "ConsumerExample.h"

#include <Pacpus/kernel/ComponentFactory.h>
#include <Pacpus/kernel/Log.h>
#include <Pacpus/kernel/InputOutputInterface.h>

using namespace pacpus;
using namespace std;

DECLARE_STATIC_LOGGER("pacpus.cityvip.test.ConsumerExample");

/// Construct the factory
static ComponentFactory<ConsumerExample> sFactory("ConsumerExample");

ConsumerExample::ConsumerExample(QString name)
    : ComponentBase(name)
{
    LOG_TRACE("constructor(" << name << ")");

    LOG_INFO("Thread " << thread.currentThread());
    LOG_INFO("Current Thread " << QThread::currentThread());
}

ConsumerExample::~ConsumerExample()
{
    LOG_TRACE("destructor");
}

void ConsumerExample::addInputs()
{
    addInput<QImage, ConsumerExample>("image", &ConsumerExample::process);
}

void ConsumerExample::addOutputs()
{
    // empty: no outputs
}

ComponentBase::COMPONENT_CONFIGURATION
ConsumerExample::configureComponent(XmlComponentConfig /*config*/)
{
    LOG_TRACE(Q_FUNC_INFO);

    // load XML parameters

    LOG_INFO("component '" << name() << "' configured");
    return ComponentBase::CONFIGURED_OK;
}

void ConsumerExample::startActivity()
{
    LOG_TRACE(Q_FUNC_INFO);
    moveToThread(&thread);
    m_counter = 0;
    
    static const char * outputFileName = "consumer.txt";
    m_file.open(outputFileName, std::ios_base::out | std::ios_base::app);
    if (!m_file.is_open()) {
        LOG_ERROR("file '" << outputFileName << "'cannot be opened");
    }

    thread.start();
    setState(MONITOR_OK);
    LOG_INFO("started component '" << name() << "'");
}

void ConsumerExample::stopActivity()
{
    LOG_TRACE(Q_FUNC_INFO);

    QMetaObject::invokeMethod(&thread, "quit");
    m_file.close();
    setState(STOPPED);
    LOG_INFO("stopped component '" << name() << "'");
}

void ConsumerExample::process(const QImage& matrix)
{
    m_file << ++m_counter << " " << road_time() << "\n" << std::flush;

    LOG_INFO("Received QIMage: "
        << "size = " << matrix.size().width()<< " x " << matrix.size().height()
        );

    // DO PROCESSING

    setState(MONITOR_OK);
}
