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

 Copyright 2012 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 "GeoToolManager.h"

#include <iostream>

#include <MvApplication.h>
#include "MvServiceTask.h"

int main(int argc, char** argv)
{
    // Set option -debug to true
    // This is needed in order to force the Save Request command
    // to save the hidden parameters too (underscore parameters).
    option opts[] = {(char*)"debug", (char*)"MARS_DEBUG",
                     (char*)"-debug", (char*)"1", t_boolean,
                     sizeof(boolean), OFFSET(globals, debug)};

    MvApplication theApp(argc, argv, nullptr, &mars, 1, opts);

    GeoToolManager gt("EDIT_MAP");

    // The applications don't try to read or write from pool, this
    // should not be done with the new PlotMod.
    //	gt.saveToPool(false);

    theApp.run();
}

//-------------------------------------------------------------

GeoToolManager::GeoToolManager(const char* kw) :
    MvService(kw)
{
    //     saveToPool(false);
}

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

    // Call function to process the request
    GeoToolService::Instance().CallGeoTool(in, out);

    std::cout << "GeoToolManager::serve out" << std::endl;
    out.print();

    return;
}

//--------------------------------------------------------

// Methods for the GeoToolService class
//

// --- METHOD:  Instance
//
// --- PURPOSE: Provide access to the singleton
//              GeoToolService class

GeoToolService&
GeoToolService::Instance()
{
    static GeoToolService GeoToolServiceInstance_;
    return GeoToolServiceInstance_;
}

GeoToolService::GeoToolService() = default;

GeoToolService::~GeoToolService() = default;

// --- METHOD:  CallGeoTool
//
// --- PURPOSE: Calls GeoTool
//
// --- INPUT:   (a) Request containing an action for GeoTool to process
void GeoToolService::CallGeoTool(MvRequest& in, MvRequest& out)
{
    // Use system command to start the appropriate GeoTool service.
    // The service will fork, register itself and read the initial request
    // to be processed. This request is stored in a temporary file whose
    // filename is passed to the service in the command line argument.

    // Save request to be processed by the appropriate service
    const char* ftemp = marstmp();
    in.save(ftemp);

    // Tell the caller that the request was done
    // The problem here is that the icon will be green even if GeoTool
    // can not process the request.
    // WE NEED TO FIND A BETTER SOLUTION!!!!!!!
    out.setVerb("REPLY");

    // Create a new task
    char* desktop = getenv("MV_DESKTOP_NAME");
    if (desktop == nullptr) {
        std::cout << "GeoToolService-> Environmental variable MV_DESKTOP_NAME not defined" << std::endl;
        return;
    }

    std::string desktopName(desktop);
    out("TARGET") = desktopName.c_str();

    // Start the approriate service
    char cmd[1024];
    sprintf(cmd, "$metview_command $METVIEW_BIN/GeoTool %s $METVIEW_QT_APPLICATION_FLAGS &", ftemp);
    system(cmd);
}

void GeoToolService::endOfTask(MvTask* task)
{
    // If error, send a message and return
    if (task->getError() != 0) {
        // int i = 0;
        // const char* msg = 0;
        // while ( msg = task->getMessage (i++ ) )

        //		PlotMod::MetviewError ( "uPlot crashed" );
        //		COUT << "GeoTool crashed" << std::endl;
    }

    // Retrieve the reply request
    auto* serviceTask = (MvServiceTask*)task;

    MvRequest replyRequest = serviceTask->getReply();
    replyRequest.print();

    // Execute the callback procedure
    // Call GeoTool
    //	MvApplication::callService ( "GeoTool", replyRequest, 0 );
}
