/***************************** 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 <fstream>
#include <iostream>
#include <sstream>
#include <string>

#include "fstream_mars_fix.h"

#include "Metview.h"
#include "MvQApplication.h"

#include <QDateTime>
#include <QDebug>

#include "MvQMailDialog.h"

std::string ftmp;


int main(int argc, char** argv)
{
    if (argc < 2) {
        marslog(LOG_EROR, "No arguments are specified");
        exit(1);
    }

    MvRequest in;
    in.read(argv[1], false, true);

    marslog(LOG_INFO, "Request:");
    in.print();

    if (!in) {
        marslog(LOG_EROR, "No request could be read from request file=%s", argv[1]);
        exit(1);
    }

    std::string outPath;
    if (const char* outPathCh = in("_OUT_REQ_FILE")) {
        outPath = std::string(outPathCh);
    }
    else {
        marslog(LOG_EROR, "No output request specified in _OUT_REQ_FILE!");
        exit(1);
    }

    std::vector<std::string> vals;
    if (!in.getValue("ITEMS", vals)) {
        exit(1);
    }

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

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

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

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

    // Compress command
    std::string cmd = std::string(getenv("METVIEW_BIN")) + "/mv_compress ";
    cmd += " -f \"" + fCompress + "\" -d \"" + fDump + "\" -m \"" + compressMethod + "\" -l \"" + fLog + "\" ";
    for (auto& val : vals) {
        cmd += "\"" + val + "\" ";
    }
    cmd += " 2>&1";

    // COUT << "command " << cmd << std::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) {
        std::ifstream inLog(fLog.c_str());
        std::string line;

        if (WEXITSTATUS(ret) == 1) {
            marslog(LOG_EROR, "Failed to perform compressiong icons!");
            while (getline(inLog, line)) {
                marslog(LOG_EROR, "%s", line.c_str());
            }
            inLog.close();
            exit(1);
        }
        else if (WEXITSTATUS(ret) > 1) {
            std::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();
            exit(1);
        }
    }
    //-----------------------------------
    // Mail dialog
    //-----------------------------------
    // Create the qt application. The appname must be unique!
    std::string appName = MvApplication::buildAppName("MvMailTo");
    MvQApplication app(argc, argv, appName.c_str(), {"mail", "window"});

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

    // 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;
        exit(0);
    }

    // mail command reuse log
    cmd = std::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
        std::string fMessage = fDump + ".msg";
        std::ofstream outMsg(fMessage.c_str());
        outMsg << md->message().toStdString() << std::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 << std::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) {
        std::ifstream inLog(fLog.c_str());
        std::string line;
        std::string msg;
        std::string detailed;
        std::string st;

        st = "ERROR";

        if (WEXITSTATUS(ret) == 1) {
            msg = "MvMail-> Failed to perform sending mail!";
        }
        else if (WEXITSTATUS(ret) > 1) {
            std::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();


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

        if (st == "ERROR") {
            marslog(LOG_EROR, "Error=%s", detailed.c_str());
        }
    }

    delete md;
}
