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

 Copyright 2020 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 "MvUiService.h"
#include "MvApplication.h"
#include "MvMiscelaneous.h"
#include "MvTmpFile.h"

#include <chrono>
#include <thread>
#include <fstream>
#include <assert.h>

#define MvUiService_DEBUG__


MvUiService::MvUiService(const char* name) :
    MvService(name)
{
    // interactive modules are not caching data (always true?)
    saveToPool(false);
}

MvUiService::~MvUiService()
{
}

void MvUiService::serve(MvRequest& in, MvRequest& out)
{
    std::cout << "serve" << std::endl;
    in.print();

    std::string mode;
    if(const char* modeCh = (const char*)in("_ACTION")) {
        mode = std::string(modeCh);
    }
    if (mode.empty()) {
        if(const char* appl = (const char*)in("_APPL")) {
            if (strcmp(appl, "macro") == 0 || strcmp(appl, "Python") == 0) {
                // this will work for wmsclient
                mode = "visualise";
            }
        }
        if(mode.empty()) {
            mode = "any";
        }
    }

    auto it = apps_.find(mode);
    if (it == apps_.end()) {
        marslog(LOG_EROR, "action=%s is not supported for request type=%s!", mode.c_str(), in.getVerb());
        setError(13);
        return;
    }

    auto appItem = it->second;
    auto appName = appItem.appName_;

    bool waitApp=false;
    if (appItem.hasOutput_) {
        waitApp = true;
    } else if (const char *waitAppCh = in("_WAIT_APP")) {
        if (strcmp(waitAppCh,"1") == 0) {
            waitApp = true;
        }
    }

    // the output request will be written into this file
    MvTmpFile outFile(false);
    in("_OUT_REQ_FILE") = outFile.path().c_str();

    if (const char* pidFileCh = in("_PID_FILE")) {
        in("_PID_FILE") = pidFileCh;
    }

    // Write request into a file
    MvTmpFile reqFile(false);
    in.save(reqFile.path().c_str(), true);

    // Start the application
    std::string cmd;
    cmd += "$metview_command $METVIEW_BIN/" + appName  + " " +
            reqFile.path() + " $METVIEW_QT_APPLICATION_FLAGS ";

    // if we do not need to wait for it
    if (!waitApp)
        cmd+="&";

    marslog(LOG_INFO, "Start appliction with command: %s", cmd.c_str());

    system(cmd.c_str());

    if (waitApp) {
        out.read(outFile.path().c_str(), false, true);
    }
}

void MvUiService::addApp(const std::string& appName, const std::vector<std::string>& actions, bool hasOutput) {
    for (auto a: actions) {
        apps_[a] = MvUiServiceAppItem(appName, a, hasOutput);
    }
}
