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

 Copyright 2017 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 <Metview.h>
#include <signal.h>

struct optvals_t
{
    int python_pid;
};


static option opts[] = {
    {(char*)"python_pid", (char*)"MV_PY_PID", (char*)"-python_pid", (char*)"0",
     t_int, sizeof(int), OFFSET(optvals_t, python_pid)},
};

optvals_t optvals = {
    0,
};

class PythonServe : public MvService
{
public:
    PythonServe(const char* name) :
        MvService(name) {}
    void serve(MvRequest&, MvRequest&);

private:
    void checkCallingPythonProcess();
};


void PythonServe::checkCallingPythonProcess()
{
    bool keepGoing = true;

    // check periodically if the calling Python process is still alive
    // note that this is not a perfect solution, as it could have
    // died and another process taken the same pid
    while (keepGoing) {
        sleep(1);
        // std::cout << "Checking pid " << optvals.python_pid << std::endl;

        int e = kill(optvals.python_pid, 0);
        // std::cout << "Checking  " << e << std::endl;
        if ((e == -1) && (errno == ESRCH)) {
            // in fact, don't print this message because it may not be true - we will get
            // to this part even if the Python code exited normally
            // marslog(LOG_WARN, "Metview detected that the calling Python process terminated without closing Metview");
            // marslog(LOG_WARN, "Metview will now close");
            keepGoing = false;
        }
    }
    marsexit(0);
}

void PythonServe::serve(MvRequest& /*in*/, MvRequest& /*out*/)
{
    // cout << "--------------PythonServe::serve() start --------------" << std::endl;
    // in.print();
    checkCallingPythonProcess();
    // cout << "--------------PythonServe::serve() end --------------" << std::endl;
}


int main(int argc, char** argv)
{
    MvApplication theApp(argc, argv, "PythonServe", &optvals, NUMBER(opts), opts);
    PythonServe ps("PYTHONCHECK");
    MvRequest rin("PYTHONCHECK");
    MvRequest rout;
    MvApplication::callService("PythonServe", rin, nullptr);
    theApp.run();
    return 0;
}
