// ******************************************
// * $Id$
// *
// *   sendOrder()
// *
// * private functies:
// *   GetExtension()
// *   connectFile()
// *   connectFtp()
// *   connectHTTP()
// *   connectMail()
// *
// ******************************************

function GetExtension(xmlDoc, xslDoc)
{
    // Company has a stylesheet defined. Use this stylesheet to generate a formatted order
    var Extension = "html";

    var xslt   = new ActiveXObject("Msxml2.XSLTemplate.6.0");
    xslDoc.resolveExternals = true; // anders op de volgende regel al:
                                    // A reference to variable or parameter 'srtnotificatiecode' cannot be resolved
    xslt.stylesheet = xslDoc;

    var xslProc = xslt.createProcessor();
    xslProc.input = xmlDoc;
    xslProc.addParameter("mode", "getExtension");
    xslProc.transform();
    var fileExt = xslProc.output;

    Log2File(2, "File ext: " + fileExt);
    // Was in Putorders.exe fout: als je outputmode xsl:output method="text" gebruitk
    // krijg je geen xml-node met bijvoorbeeld <format><extension>csv</extension></format>
    // maar gewoon csv
    // Uiteindelijk eindigde je dan met fallback naar txt!!
    // var extDoc = SafeLoadTextXML(fileExt);
    var extDoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
    extDoc.async = false;
    extDoc.loadXML(fileExt);

    if (extDoc.parseError.errorCode != 0)
    {
        // no valid xml structure, doctype of output is probably in text format
        Log2File(1, "Output format is text");
        Extension = "txt";
    }
    else
    {
        extDoc.setProperty("SelectionLanguage", "XPath");
        var extensionNode = extDoc.selectSingleNode("//format/extension")
        if (!extensionNode)
        {
            Log2File(2, "extensionNode Is Nothing");
            Extension = "html";
        }
        else
        {
            Log2File(2, "extensionNode is defined");
            Extension = extensionNode.text;
        }
        Log2File(2, "Extension: " + Extension);
    }
    return Extension;
}

// JGL Volgens mij is er juni 2014 geen enkele klant die dit gebruikt.
function connectFile(p_connect, p_textstream, p_filename)
{
        var filename = p_connect.CurrentAddress + p_filename;
        Log2File(1, "Sending File as: " + filename);

        p_textstream.SaveToFile(filename, 2); // adSaveCreateOverWrite

        var resultcode = 0;
        var errText = "";
        Log2File(2, "*< connectFile");

        return {resultcode: resultcode, errtext: errText};
}


function connectHTTP( p_connect
                    , p_textstream
                    , p_xsldoc
                    , p_bedrijfadres
                    , p_filename // unused
                    )
{
    Log2File(1, "Sending HTTP (body {0} bytes)".format(p_textstream.Size));

    var resultcode = 0; // in principe succes
    var errText = "";
    var mode = "";
    var submitResult;

    if (p_bedrijfadres.ordermode == 0)
    {
        mode = "HTTP";
        Log2File(2, "Before SendOrder submitHTTP");
        submitResult = submitHTTP( p_connect
                                 , p_textstream
                                 , p_bedrijfadres);
        Log2File(2, "HTTPresult: " + submitResult);
    }
    else if (p_bedrijfadres.ordermode & 1)
    {
        mode = "SOAP";
        Log2File(2, "Before SendOrder SubmitDOMSOAP");
        submitResult = submitDOMXSLSOAP( p_connect
                                       , p_textstream
                                       , p_xsldoc
                                       , p_bedrijfadres
                                       );
        Log2File(2, "(base64-decoded) response: " + submitResult)
        // SOAPresult bevat nu doorgaans een cXML response, anders was er wel een error geraised
        //
        // Van cxml gaan we nog weer controleren of het verzendresultaat goed is
    }
    else
    {
        Log2File(0, "Ongeldig order_mode: " + p_bedrijfadres.ordermode);
    }

    // xml maar even eruit gehaald omdat API requests soms falen en deze geven dan geen geldige
    // xml terug.
    var contentType = "";
    if (submitResult)
        contentType = /*global*/ lastContentType;
    if (p_bedrijfadres.error_handling && contentType && contentType.indexOf("xml") != -1)
    {
        var XMLresult = new ActiveXObject("Msxml2.DOMDocument.6.0");
        var xmlDoc = SafeLoadTextXML(submitResult);

        TestAndRaiseAnXMLError("Error in xXML "+mode+" response", xmlDoc);
        if (p_xsldoc)
        {
            xmlDoc.transformNodeToObject(p_xsldoc, XMLresult);

            Log2File(3, "(c)XML response: " + XMLresult.xml);
            TestAndRaiseAnXMLError("Analyseren (c)XML response", XMLresult);
            if (XMLresult.text)
            {
                Log2File(1, "(c)XML resultaat error: " + XMLresult.xml);
                resultcode = 1; // Geweigerd
                errText = XMLresult.text;
            }
        }
        else
        {
            Log2File(3, "(c)XML response: niet gegenereerd");
        }
    }

    Log2File(2, "*< connectHTTP");

    return {resultcode: resultcode, errtext: errText, response: submitResult};
}


function connectFTP( p_connect
                   , p_bedrijfadres
                   , p_textstream
                   , p_filename
                   , p_bijlagen
                   )
{
    Log2File(1, "Sending FTP as file: " + p_filename + " (" + p_textstream.Size + " bytes)");
    var FTPresult = sendFTP(p_connect, p_filename, p_textstream); // send text data
    //
    // Stuur alle flexfiles (type M(ap) en F(file)) ook mee
    if (p_bijlagen.refkey)
    {
        var objFso  = new ActiveXObject("Scripting.FileSystemObject");

        var sql_km = "";
        switch (p_bijlagen.module)
        {
            case "MLD": sql_km = "SELECT mld_kenmerk_key FROM mld_kenmerk WHERE mld_kenmerk_niveau IN ('O','P')"; break;
            case "BES": sql_km = "SELECT bes_kenmerk_key FROM bes_kenmerk WHERE bes_kenmerk_type = 'B'"; break;
        }

        if (sql_km.length)
            sql_km = " AND b.fac_bijlagen_kenmerk_key IN (" + sql_km + ")";

        var sql = "SELECT r.fac_bijlagen_disk_directory"
                + "     , r.fac_bijlagen_filename"
                + "     , r.fac_bijlagen_file_size"
                + "  FROM fac_bijlagen r"
                + "     , fac_bijlagen b"
                + " WHERE b.fac_bijlagen_root_key = r.fac_bijlagen_key"
                + "   AND b.fac_bijlagen_verwijder IS NULL"
                + "   AND r.fac_bijlagen_verwijder IS NULL"
                + "   AND b.fac_bijlagen_module = " + safe.quoted_sql(p_bijlagen.module)
                + "   AND b.fac_bijlagen_refkey = " + p_bijlagen.refkey
                + sql_km;
        var oRs = Oracle.Execute(sql);
        while (!oRs.eof)
        {
            var f_path = oRs("fac_bijlagen_disk_directory").Value;
            var f_name = oRs("fac_bijlagen_filename").Value;
            var f_size = oRs("fac_bijlagen_file_size").Value;
            var filepath = S("flexfilespath") + "/" + f_path + "/" + f_name;
            if (objFso.FileExists(filepath))
            {
                // Van p_filename de extensie eraf halen.
                var filename = safe.filename(p_filename.split('.')[0] + "_" + f_name);
                Log2File(1, "Sending attachment: " + filepath + " (" + f_size + " bytes)");
                FTPresult = sendFTP(p_connect, filename, "", filepath);
            }
            else
            {
                Log2File(1, "Error: attachment '" + filepath + "' not found. Ignoring.");
            }
            oRs.MoveNext();
        }
        oRs.Close();
    }

    var resultcode = -1;
    var errText = "";
    if (FTPresult)
    {
        resultcode = 2;
    }
    Log2File(2, "*< connectFTP");

    return {resultcode: resultcode, errtext: errText};
}

// Vooralsnog zonder bijlagen
function connectSFTP( p_connect
                   , p_bedrijfadres
                   , p_textstream
                   , p_filename
                   )
{
    Log2File(1, "Sending SFTP as file: " + p_filename + " (" + p_textstream.Size + " bytes)");
    var FTPresult = sendSFTP(p_connect, p_filename, p_textstream); // send text data
    //
    // Vooralsnog zonder bijlagen

    var resultcode = -1;
    var errText = "";
    if (FTPresult)
    {
        resultcode = 2;
    }
    Log2File(2, "*< connectSFTP");

    return {resultcode: resultcode, errtext: errText};
}

function connectMail( p_connect
                    , p_textstream
                    , p_xmlDoc
                    , p_bedrijfadres
                    , p_xslPath
                    , p_ordernr
                    , p_order_key
                    , p_sender
                    , XMLnode
                    , p_filename
                    , p_bijlagen
                    , p_subject
                    )
{
    Log2File(2, "*> connectMail");
    Log2File(2, "Sending email as: " + p_filename);
    var resultcode = -1;
    var errText = "";

    if ( S("puo_fromaddress") && S("puo_fromaddress") != "null" && S("puo_fromaddress") != "nodefault")
    {
        // Compose mail
        Log2File(2, "Before SendMail");
        var body = "Opdracht nr. " + p_ordernr + " is middels Facilitor bij u geplaatst."
                 + " De specificatie van de bestelling is bijgevoegd als document: " + p_filename;
        var mailResult  = false;
        var encryptpass = "";

        if ((p_bedrijfadres.ordermode & 2) != 0) // Ooit bedacht om vertaaldocumenten encryped te versturen
        {                                         // Dat werd echter niet door virusscanners geaccepteerd dus
                                                  // nooit in gebruik genomen
            encryptpass = p_bedrijfadres.certificateName;
        }

        var mailsubject = getMailSubject(XMLnode, p_order_key, p_ordernr, p_subject);

        // Alleen txt en html kunnen eventueel in de mailbody
        var mail_to = p_connect.mailto;
        var params = { attachPassword: encryptpass
                     , include_file:   p_bedrijfadres.AttachFile
                     , cc          :   S("puo_cc")
                     , bcc         :   S("puo_bcc")
                     , receiptto   :   S("puo_receiptto")
                     , bedrijfadres:   p_bedrijfadres
                     , module      :   p_bijlagen.module
                     , niveau      :   p_bijlagen.niveau
                     , refkey      :   p_bijlagen.refkey
                     , kenmerk_key :   (p_bijlagen.kenmerk_key ? p_bijlagen.kenmerk_key : null)
                     , fcltid      :   XMLnode + ":" + p_order_key // komt in message header X-FCLT-fcltid
                     };
        if ((p_bedrijfadres.ordermode & 1) == 0)  // In body
        {
            if (p_bedrijfadres.extension == "html")
            {
                // Use the mailer translation function in case the html is added to the body
                // to be able to add the logo and to include the email parameter
                var content = XML2HTML( p_xmlDoc
                                      , p_xslPath
                                      , "" // waarom geen p_code hier (met de srtnotificatie?
                                      , "email"
                                      , p_bedrijfadres
                                      );
                LogString2File(2, "email_body", content, "html");

                params.notimode = "email";
                params.attachFileName = p_filename; //JGL Volgens mij don't care parameter
                mailResult = sendMail( p_sender
                                     , mail_to
                                     , mailsubject
                                     , ""
                                     , content
                                     , params
                                     );
            }
            else
            {
                mailResult = sendMail( p_sender
                                     , mail_to
                                     , mailsubject
                                     , stream2text(p_textstream)
                                     , ""
                                     , params
                                     );
            }
        }
        else // Plain body met verwijzing naar de attachment, waarschijnlijk een XML
        {
            Log2File(2, "Sending email as: " + p_filename);
            params.attachFileName = p_filename;
            params.attachStream   = p_textstream;
            mailResult = sendMail( p_sender
                                 , mail_to
                                 , mailsubject
                                 , body
                                 , ""
                                 , params
                                 );
        }

        if (mailResult)
        {
            resultcode = 0; // Bij errors is er wel een exception geweest
        }
        else
        {
            Log2File(0, "Ordering email not sent.");
        }
    }
    else
    {
        Log2File(0, "Ordering email not sent because puo_fromaddress is not set");
    }
    Log2File(2, "*< connectMail");

    return {resultcode: resultcode, errtext: errText};
}


// Public functies
function SendOrder( p_connect
                   , p_xmlDoc
                   , p_bedrijfadres
                   , p_xslPath
                   , p_ordernr
                   , p_order_key
                   , p_sender
                   , XMLnode
                   , p_code
                   , p_bijlagen
                   , p_subject
                   )
{
    // Input:
    // Order_mode 0=in body, 1=attachment
    //           +2='encrypt' opdracht mail attachments met 'certificateName'
    //           +4='donot doublebase64encode'
    // Resultaat:
    //   0 Alles ok
    //  -1 Technische fout, bijvoorbeeld geen Certificaat, geen HTTPS verbinding of ongeldige SOAP envelop
    //   1 Logische fout in bijvoorbeeld de cXML zoals leverancier niet bekend o.i.d.
    //     errText wordt eventueel met een tekst gevuld
    //   2 OK maar geen bevestiging ontvangen bij mail, file en FTP
    Log2File(2, "*> sendOrder");
    try
    {
        if (!p_xslPath && p_bedrijfadres.encoding != 2) // Voor JSON is XSL niet nodig
        {
          throw new UserException(1000, "PutOrders", "No path specified");
        }
//        if (p_bedrijfadres.url.toLowerCase().includes("topdesk.asp?") && !p_bedrijfadres.XSLbedr)
//        { // Voor TopDesk moet er altijd een xsl worden meegegeven!
//          throw new UserException(1000, "PutOrders", "No TopDesk xsl-path specified");
//        }

        var prevent_sending = puo_hook.callhook("prevent_sending", { p_connect: p_connect,
                                                                     p_xmlDoc: p_xmlDoc,
                                                                     p_bedrijfadres: p_bedrijfadres },
                                                false); // default false voor niet prevenden
        if (prevent_sending)
        {
            Log2File(1, "Op verzoek hookfunction/prevent_sending toch maar niet sturen");
            return {resultcode: 0, errtext: errText };
        }

        var resultcode = -1;
        var errText = "Onbekende fout";

        Log2File(3, "In SendOrder sender=" + p_sender);
        // Company has a stylesheet defined. Use this stylesheet to generate a formatted order
        // Voor AKZA/GTI is dit bijvoorbeeld een eigen formaat
        // Voor UWVA/Westplant is dit een cXML
        // Load stylesheet
        var xslDoc = null;
        if (p_xslPath && p_bedrijfadres.encoding != 2)
        {
            Log2File(1, "Load company style: " + p_xslPath);
            var xslDoc = SafeLoadFileXSL(p_xslPath);
            xslDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'"); // verderop nodig
        }

        if (p_bedrijfadres.encoding == 2)
            p_bedrijfadres.extension = "json"; // alleen voor logfiles

        if (!p_bedrijfadres.extension)
        {
            p_bedrijfadres.extension = GetExtension(p_xmlDoc, xslDoc) // Old style via XSL
        }

        var streamResult = new ActiveXObject("ADODB.Stream");
        streamResult.Type = 2; // adTypeText
        if (p_bedrijfadres.encoding == 2) // JSON
        {
            if (!puo_hook.hashook("xmlDoc_to_json"))
            {
              throw new UserException(1000, "PutOrders", "JSON results need plugin function xmlDoc_to_json");
            }
            var json_data = puo_hook.callhook("xmlDoc_to_json", { p_connect: p_connect,
                                                                  p_xmlDoc: p_xmlDoc,
                                                                  p_bedrijfadres: p_bedrijfadres,
                                                                  p_xslPath      : p_xslPath,
                                                                  p_ordernr      : p_ordernr,
                                                                  p_order_key    : p_order_key,
                                                                  p_sender       : p_sender,
                                                                  XMLnode        : XMLnode,
                                                                  p_code         : p_code,
                                                                  p_bijlagen     : p_bijlagen,
                                                                  p_subject      : p_subject });
            streamResult.Charset = p_bedrijfadres.charset || 'utf-8';
            streamResult.Open();
            var JSON_text = JSON.stringify(json_data);
            LogString2File(3, "payload", JSON_text, "json");
            streamResult.WriteText(JSON_text);
            streamResult.Position = 0;
        }
        else if (p_bedrijfadres.extension) // Doe eventueel wat XSL-transforms
        {
            if (p_bedrijfadres.charset)
            {
                streamResult.Charset = p_bedrijfadres.charset;
            }
            else // autodetect
            {
                streamResult.Charset = 'utf-8';

                // Kijk of er in de XSL naar een andere encoding wordt getransformeerd
                // Naar Windows-1252 kregen we namelijk problemen bij Extended ASCII
                // karakters op Windows 2008 (AAIT#31212)
                if (xslDoc.selectSingleNode("//xsl:output"))
                {
                    var enc = xslDoc.selectSingleNode("//xsl:output").getAttribute("encoding");
                    if (enc)
                    {
                        Log2File(2, "Forcing stream encoding to: " + enc);
                        streamResult.Charset = enc;
                    }
                }
            }

            streamResult.Open();
            if (p_bedrijfadres.extension == "xml" || p_bedrijfadres.extension == "cxml")
            {
                result = XML2HTML( p_xmlDoc
                                 , p_xslPath
                                 , p_code
                                 , ""
                                 , p_bedrijfadres
                                 )

                var XMLResult = new ActiveXObject("Msxml2.DOMDocument.6.0");
                XMLResult.async = false;
                XMLResult.loadXML(result);
                TestAndRaiseAnXMLError("Error in SendOrder XML2HTML result", XMLResult, result);

                // Eventuele attachements inplakken
                // Log2File(2, "Order: " + XMLResult.xml);
                mergeXMLAttachments(XMLResult, p_xslPath);
                XMLResult.save(streamResult);
                //Log2File(2, "Order2: " + XMLResult.xml);
            }
            else // Bijvoorbeeld csv
            {
                p_xmlDoc.transformNodeToObject(xslDoc, streamResult);
            }
            LogStream2File(2, "transformed", streamResult, p_bedrijfadres.extension);
            streamResult.Position = 0;
        }

        if (p_bedrijfadres.extension) // Nu verder met het echte versturen
        {
            // file naam mag geen / bevatten
            var filename = p_ordernr + "." + p_bedrijfadres.extension;
            filename = safe.filename(filename);

            var connectResult = {};
            if (p_connect.Connected)
            {
                if (p_connect.isFile)
                {
                    filename = "Opdr_" + filename;
                    connectResult = connectFile( p_connect
                                               , streamResult
                                               , filename
                                               );
                }
                else if (p_connect.isHTTP || p_connect.isHTTPS)
                {
                    connectResult = connectHTTP( p_connect
                                               , streamResult
                                               , xslDoc // voor de terugweg
                                               , p_bedrijfadres
                                               , filename
                                               );
                }
                else if (p_connect.isFTP)
                {
                    filename = "o_" + filename;
                    connectResult = connectFTP( p_connect
                                              , p_bedrijfadres
                                              , streamResult
                                              , filename
                                              , p_bijlagen
                                              );
                }
                else if (p_connect.isSFTP)
                {
                    filename = "o_" + filename;
                    connectResult = connectSFTP( p_connect
                                              , p_bedrijfadres
                                              , streamResult
                                              , filename
                                              );
                }
                else if (p_connect.isMail)
                {
                    filename = "Opdr_" + filename;
                    connectResult = connectMail( p_connect
                                               , streamResult
                                               , p_xmlDoc
                                               , p_bedrijfadres
                                               , p_xslPath
                                               , p_ordernr
                                               , p_order_key
                                               , p_sender
                                               , XMLnode
                                               , filename
                                               , p_bijlagen
                                               , p_subject
                                               );
                }
                else
                {
                    // no connection
                }
            } // p_connected.Connected
            resultcode = connectResult.resultcode;
            errText = connectResult.errtext;
        } //extension != ""
    }
    catch(e)
    {
        Log2File(0, toDateTimeString(new Date()) + " Error (SendOrder) sending " + (filename||"") + ": " + e.description, "W");
        resultcode = -1;
        errText = e.description;
    }
    finally
    {
    }
    Log2File(2, "*< sendOrder");

    if (errText)
        errText = String(errText).replace(/\r\n$/, ""); // Er staat nogal eens een loze newline achteraan de foutmelding
    var SendOrderResult = {resultcode: resultcode, errtext: errText, response: resultcode>=0?connectResult.response:null};

    puo_hook.callhook("sendorderresult", { SendOrderResult: SendOrderResult,
                                           p_connect      : p_connect,
                                           p_xmlDoc       : p_xmlDoc,
                                           p_bedrijfadres : p_bedrijfadres,
                                           p_xslPath      : p_xslPath,
                                           p_ordernr      : p_ordernr,
                                           p_order_key    : p_order_key,
                                           p_sender       : p_sender,
                                           XMLnode        : XMLnode,
                                           p_code         : p_code,
                                           p_bijlagen     : p_bijlagen,
                                           p_subject      : p_subject
                                         });

    return SendOrderResult;
}

function getMailSubject(pXMLnode, pOpdrKey, ordernr, p_subject)
{
    var sqlS = "";
    var MailSubject = "";
    switch (pXMLnode)
    {
        case "opdracht":
            {
                MailSubject = S("puo_subjectprefixmld");
                sqlS = "SELECT mld.opdrsprintf(" + safe.quoted_sql(MailSubject) + "," + pOpdrKey + ") subj FROM DUAL";
                break;
            }
        case "bestelopdr":
            {
                MailSubject = S("puo_subjectprefix");
                sqlS = "SELECT bes.opdrsprintf(" + safe.quoted_sql(MailSubject) + "," + pOpdrKey + ") subj FROM DUAL";
                break;
            }
        case "contract":
            {
                MailSubject = S("puo_subjectprefixcnt");
                sqlS = "SELECT cnt.sprintf("     + safe.quoted_sql(MailSubject) + "," + pOpdrKey + ") subj FROM DUAL";
                break;
            }
        case "reservering":
            {
                MailSubject = S("puo_subjectprefixres");
                sqlS = "SELECT res.sprintf(" + safe.quoted_sql(MailSubject) + "," + pOpdrKey + ") subj FROM DUAL";
                break;
            }
        default:
            return p_subject;
    }
    if (MailSubject.indexOf("##") == -1)
    {
        MailSubject = MailSubject + ordernr; // Geen ##, backwards compatible toch nummer erbij
    }
    else
    {
        var oRsS = Oracle.Execute(sqlS);
        MailSubject = oRsS("subj").value;
        oRsS.Close();
    }

    return MailSubject;
}

