/***************************** LICENSE START ***********************************

 Copyright 2015 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <QDebug>
#include <QSocketNotifier>
#include <QCoreApplication>
#include <QMainWindow>

#include "MvQService.h"
#include "MvApplication.h"

#define MVQSERVICE_DEBUG__

MvQService::MvQService(const char* name) :
    MvService(name),
    socketNotifier_(nullptr),
    win_(nullptr)
{
    saveToPool(false);  // interactive modules are not caching data (always true?)
}

MvQService::~MvQService()
{
}

void MvQService::messageCallbackCore(svcid* id, request* r, void* obj)
{
#ifdef MVQSERVICE_DEBUG__
    std::cout << "MvQService::messageCallback" << std::endl;
    print_all_requests(r);
#endif
    if (MvQService* s = static_cast<MvQService*>(obj))
        s->messageCallback(id, r);
}

void MvQService::messageCallback(svcid* id, request* r)
{
    if (strcmp(r->name, "RAISE_WINDOW") == 0 && win_) {
        const char* pidStr = QString::number(QCoreApplication::applicationPid()).toStdString().c_str();
        if (pidStr && strcmp(get_value(r, "PID", 0), pidStr) == 0) {
#ifdef MVQSERVICE_DEBUG__
            std::cout << "   raise window for PID=" << pidStr << std::endl;
#endif
            win_->showNormal();
            win_->raise();
        }
    }
}

void MvQService::registerToDesktop(QMainWindow* win)
{
    if (win == nullptr)
        return;

    win_ = win;

    add_message_callback(MvApplication::getService(), NULL,
                         messageCallbackCore, (void*)this);

    MvRequest r("REGISTER_QTAPP_PID");
    r("PID") = QString::number(QCoreApplication::applicationPid()).toStdString().c_str();
    sendProgress(r);

    // setupSocketNotifier() must be called to make the callback work
}

// The MARS event loop is not running in the forked MvService instances. Using this function
// we are able to receive data from Event and process it accordingly.
void MvQService::setupSocketNotifier()
{
    if (socketNotifier_)
        return;

    // Create socket notifier
    // The dataReceived function will be called everytime
    // there is data available in the socket
    socketNotifier_ = new QSocketNotifier(Id->s->soc, QSocketNotifier::Read, this);
    QObject::connect(socketNotifier_, SIGNAL(activated(int)),
                     this, SLOT(slotDataReceived(int)));
}

void MvQService::slotDataReceived(int)
{
    // process data from the socket
    //std::cout << "MvQService::slotDataReceived" << std::endl;
    process_service(Id->s);
    //std::cout << "  -->processed" << std::endl;
}
