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

 Copyright 2016 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 <unistd.h>
#include <pwd.h>

#include <iostream>
#include "Metview.h"
#include "MvQService.h"
#include "MvQServiceApplication.h"

#include <QDateTime>
#include <QDebug>

#include "MvQMailDialog.h"

string ftmp;

using namespace std;

// Globals
int ac;
char** av;

class Base : public MvQService
{
protected:
    Base(char* a) :
        MvQService(a) {}
};

class MvMail : public Base
{
public:
    MvMail() :
        Base("SENDMAIL") {}
    void serve(MvRequest&, MvRequest&);
};

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

    vector<string> vals;
    if (!in.getValue("ITEMS", vals))
        return;

    //-----------------------------------
    // Create tar file
    //-----------------------------------

    string userName;
    struct passwd* pw = getpwuid(getuid());
    if (pw) {
        userName = string(pw->pw_name);
    }

    string dateStr = QDateTime::currentDateTime().toString("yyyyMMdd_hhmm").toStdString();

    //Dump file name + tar file name
    string fDump(marstmp());
    string compressMethod = "tgz";
    string compressSuffix = "tar.gz";
    string fCompress      = string(mdirname(fDump.c_str())) + "/mv_icons_" +
                       userName + "_" + dateStr + "." + compressSuffix;
    string fLog = fDump + ".log";

    //Compress command
    string cmd = string(getenv("METVIEW_BIN")) + "/mv_compress ";
    cmd += " -f \"" + fCompress + "\" -d \"" + fDump + "\" -m \"" + compressMethod + "\" -l \"" + fLog + "\" ";
    for (vector<string>::iterator it = vals.begin(); it != vals.end(); it++) {
        cmd += "\"" + (*it) + "\" ";
    }
    cmd += " 2>&1";

    //COUT << "command " << cmd << endl;

    int ret = system(cmd.c_str());

    //If the script failed read log file and
    //write it into LOG_EROR
    if (ret == -1 || WEXITSTATUS(ret) != 0) {
        ifstream inLog(fLog.c_str());
        string line;

        if (WEXITSTATUS(ret) == 1) {
            setError(1, "MvMail-> Failed to perform compressiong icons!");
            //marslog(LOG_EROR,"Failed to perform compressiong icons!");
            while (getline(inLog, line)) {
                setError(1, line.c_str());
                //marslog(LOG_EROR,"%s",line.c_str());
            }
            inLog.close();
            //setError(13);
            return;
        }
        else if (WEXITSTATUS(ret) > 1) {
            ostringstream oss;
            oss << "MvMail-> Compressing icons failed with exit code: " << WEXITSTATUS(ret);
            setError(1, oss.str().c_str());
            //marslog(LOG_EROR,"Compressing icons failed with exit code: %d !",WEXITSTATUS(ret));
            while (getline(inLog, line)) {
                setError(1, line.c_str());
                //marslog(LOG_EROR,"%s",line.c_str());
            }
            inLog.close();
            //setError(13);
            return;
        }
    }
    //-----------------------------------
    // Mail dialog
    //-----------------------------------

    //Create the qt application
    MvQServiceApplication app(ac, av);

    //Initialise resorces from a static library (libMvQtGui)
    Q_INIT_RESOURCE(mail);

    MvQMailDialog* md = new MvQMailDialog(fCompress, fDump);
    md->show();

    //Listen to the mars event loop!
    setupSocketNotifier();

    //Enter the app loop
    app.exec();

    //Now we have left the qt event loop

    //-----------------------------------
    // Send mail
    //-----------------------------------

    if (md->result() == QDialog::Rejected || md->to().isEmpty()) {
        //This should be deleted
        //fCompress
        delete md;
        return;
    }

    //mail command reuse log
    cmd = string(getenv("METVIEW_BIN")) + "/mv_mail ";

    cmd += " -t \"" + md->to().toStdString() + "\" ";

    if (!md->cc().isEmpty())
        cmd += " -c \"" + md->cc().toStdString() + "\" ";

    if (!md->subject().isEmpty())
        cmd += " -s \"" + md->subject().toStdString() + "\" ";

    if (!md->message().isEmpty()) {
        //Write message into file
        string fMessage = fDump + ".msg";
        ofstream outMsg(fMessage.c_str());
        outMsg << md->message().toStdString() << endl;
        outMsg.close();

        cmd += " -m \"" + fMessage + "\" ";
    }

    cmd += " -f \"" + fCompress + "\" -l \"" + fLog + "\"";

    //cmd+= " -t \"" + md->to().toStdString() + "\" " +
    //       (!md->cc().isEmpty())?( "-c \"" + md->cc().toStdString() + "\" "
    //      "\" -s \"" + md->subject().toStdString() + "\" -m \"" + md->message().toStdString() +
    //      "\" -f \"" + fCompress + "\" -l \"" + fLog + "\"" ;

    cmd += " 2>&1";

    //COUT << "command " << cmd << endl;

    ret = system(cmd.c_str());

    //If the script failed read log file and
    //write it into LOG_EROR
    if (ret == -1 || WEXITSTATUS(ret) != 0) {
        ifstream inLog(fLog.c_str());
        string line;
        string msg;
        string detailed;
        string st;

        st = "ERROR";

        if (WEXITSTATUS(ret) == 1) {
            msg = "MvMail-> Failed to perform sending mail!";
        }
        else if (WEXITSTATUS(ret) > 1) {
            stringstream ss;
            ss << "MvMail-> Sending mail failed with exit code: " << WEXITSTATUS(ret) << "!";
            msg = ss.str();
        }

        setError(1, msg.c_str());
        //marslog(LOG_EROR,"%s",msg.c_str());
        while (getline(inLog, line)) {
            //marslog(LOG_EROR,"%s",line.c_str());
            detailed += line + "\n";
        }
        inLog.close();

        out             = MvRequest("MESSAGE");
        out("STATUS")   = st.c_str();
        out("TEXT")     = msg.c_str();
        out("DETAILED") = detailed.c_str();

        if (st == "ERROR") {
            setError(1, detailed.c_str());
            return;
        }
    }

    delete md;

    //exit(0);
}

int main(int argc, char** argv)
{
    ac = argc;
    av = argv;

    MvApplication theApp(argc, argv);

    MvMail mail;

    theApp.run();
}
