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

#include "fstream_mars_fix.h"

#include "Metview.h"
#include "MvQApplication.h"
#include "MvCompressRun.h"
#include "MvExitStatus.h"
#include "MvMiscellaneous.h"
#include "MvTmpFile.h"

#include <QDateTime>
#include <QDebug>

#include "MvQMailDialog.h"

std::string ftmp;

//---------------------------------------------------
// Create tar.gz file from the icons using import
//---------------------------------------------------

void makeTarGz(MvRequest& in, const std::string& reqOutPath, std::unique_ptr<MvTmpFile>& compressFile, std::unique_ptr<MvTmpFile>& dumpFile)
{
    MvRequest compOut;
    std::string userName;
    struct passwd* pw = getpwuid(getuid());
    if (pw) {
        userName = std::string(pw->pw_name);
    }

    std::string compressFormat = "tgz";
    std::string compressSuffix = "tar.gz";

    dumpFile = std::unique_ptr<MvTmpFile>(new MvTmpFile());
    std::string dateStr = QDateTime::currentDateTime().toString("yyyyMMdd_hhmm").toStdString();
    compressFile = std::unique_ptr<MvTmpFile>(new MvTmpFile("/mv_icons_" + userName + "_" + dateStr + "." + compressSuffix));

    in("PARAM") = compressFormat.c_str();
    metview::compress::MvCompressRun compressor;
    compressor.enableMailMode(compressFile->path(), dumpFile->path());
    int compRet =  compressor.run(in, compOut);

    if (compRet != 0) {
        std::string st;
        compOut.getValue("STATUS", st, false);
        if (st == "ERROR") {
            std::string msg;
            compOut.getValue("TEXT", msg, true);
            msg = "MvMailTo failed!\n" + msg;
            marslog(LOG_EROR, "Error=%s", msg.c_str());
            compOut("TEXT") = msg.c_str();
        }
        compOut.print();
        compOut.save(reqOutPath.c_str());
        exit(1);
    }
}

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.gz file from the icons using import
    //---------------------------------------------------

    std::unique_ptr<MvTmpFile> compressFile, dumpFile;
    makeTarGz(in, outPath, compressFile, dumpFile);

    //-----------------------------------
    // 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(compressFile->path(), dumpFile->path());
    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);
    }

    MvTmpFile fLog, fMessage;

    // mail command
    std::string 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 = dumpFile + ".msg";
        std::ofstream outMsg(fMessage.path().c_str());
        outMsg << md->message().toStdString() << std::endl;
        outMsg.close();

        cmd += " -m \"" + fMessage.path() + "\" ";
    }

    cmd += " -f \"" + compressFile->path() + "\" -l \"" + fLog.path() + "\"";

    // 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;

    MvExitStatus ret(system(cmd.c_str()));

    // If the script failed read log file and
    // write it into LOG_EROR
    if (!ret.isSuccess()) {
        std::string msg;
        std::string detailed;
        std::string st = "ERROR";

        if (ret.isError()) {
            if (ret.exitCode() == 1) {
                msg = "MvMailTo-> Failed to perform sending mail!";
            }
            else {
                msg = "MvMailTo-> Sending mail failed with exit code: " + std::to_string(ret.exitCode()) + "!";
            }
        }

        detailed = metview::textFileContents(fLog.path());

        // setError(1, msg.c_str());
        marslog(LOG_EROR, "%s", msg.c_str());

        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;
}
