/*
    $Id$

    File:        wsf_shared.js
    Description: Hulpfuncties voor WSF bestanden
    Context:     bijvoorbeeld gen_import.wsf
    Note:        We herhalen hier de noodzakelijke functies van appl/shared/shared.inc

*/

function padout(number)
{ return (number < 10) ? "0" + number : number;
}
// Noot: altijd jaar vooraan, goed voor logfiles, niet bedoeld voor presentatie
function toDateString(jsDate)
{
    return padout(jsDate.getFullYear())  + "-" + padout(jsDate.getMonth() + 1) + "-" + padout(jsDate.getDate());
}
function toDateTimeString(jsDate)
{
    return toDateString(jsDate) + " "
         + padout(jsDate.getHours()) + ":" + padout(jsDate.getMinutes())   + ":" + padout(jsDate.getSeconds());
}
function __Log(s, params)
{
    var params = params || {}; // default logging met timestamp.
    var severity = params.severity || "I";
    WScript.Echo(toDateTimeString(new Date) + ";" + severity + ";" + s);
}
function __DoLog(s, params)
{
    __Log(s, params);
}
function subfolderKey(pNiveau, pKey)
{
    var keyStr = "0000000" + pKey;
    var subfolder = pNiveau + keyStr.substr(keyStr.length - 7, 4) + "___/" + pNiveau + pKey;
    return subfolder;
}
function Fill(i, c)
{   // Maakt een string met i tekens 'char'.
    return new Array(i + 1).join(c);
}

function isOffline()
{
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    if (fso.FileExists("../forceonline.txt"))
        return false;
    if (fso.FileExists("../offline.html"))
        return true;
    if (fso.FileExists("../../offline.html"))
        return true;
    if (fso.FileExists("../../../temp/offline.html"))
        return true;

    return false;
}

function Connect2Oracle(p_params)
{
    var params = {};
    if (typeof p_params == "string")
        params.modulename = p_params;
    else if (typeof p_params == "object")
        params = p_params;

    var udl = (params.udl ? params.udl : "../Oracle.udl");
    var Oracle = new ActiveXObject("ADODB.Connection");
    Oracle.Open('File Name='+udl);
    if (params.modulename)
    {   // Vind je terug in Toad/Session browser
        var sql = "BEGIN DBMS_APPLICATION_INFO.SET_MODULE (" + safe.quoted_sql(params.modulename) + ", NULL); END;";
        Oracle.Execute(sql);
    }
    sql = "BEGIN fac.initsession(" + (params.language ? safe.quoted_sql(params.language) : "NULL") + "); END;"
    Oracle.Execute(sql);
    __Log("Session initiated: " + sql);
    return Oracle;
}

String.prototype.format = function()
{
    var formatted = this;
    for (var i = 0; i < arguments.length; i++)
    {
        if (typeof arguments[i] == "string")
          arguments[i] = arguments[i].replace(/\$/g, '$$$$');
        var regexp = new RegExp('\\{'+i+'\\}', 'gi');
        formatted = formatted.replace(regexp, arguments[i]);
    }
    return formatted;
};

Date.prototype.toSQL = function toSQL(withTime, withSeconds)
{   // extracted from shared.inc
    var year = this.getFullYear();
    if (year < 1000 || year > 9999)
        __Log("Invalid year " + this.toLocaleString()); // Net iets minder erg dan ORA-01830

    var str = padout(this.getDate()) + "-" + padout(this.getMonth() + 1) + "-" + padout(this.getFullYear())
    var dateformat = "DD-MM-YYYY";
    if (withTime)
    {
        str += " " + padout(this.getHours()) + ":" + padout(this.getMinutes());
        dateformat += " HH24:MI";
        if (withSeconds)
        {
            str += ":" + padout(this.getSeconds());
            dateformat += ":SS";
        }
    }
    return "to_date(" + safe.quoted_sql(str) + ", '" + dateformat + "')";
}

safe = { // extracted from shared.inc
    quoted_sql: function (tekst, maxlen) // maxlen is optioneel
    {
        if (tekst == null)
            return "NULL";
        if (!maxlen)
            maxlen = 4000;
        tekst = tekst.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]+/g, "?");
        tekst = tekst.substr(0, maxlen);
        return "'" + tekst.replace(/\'/g,"''") + "'"; // " syntax highlight correctie
    },
    quoted_sql_upper: function (tekst, maxlen)
    {
        if (tekst == null)
            return "NULL";
        return safe.quoted_sql(tekst.toUpperCase(), maxlen);
    },
    quoted_sql_join: function (tekstarr, toupper) // Vooral voor IN () clausules met tekstwaardes
    {
        if (!tekstarr || !tekstarr.length)
            return "NULL";

        var safearr = [];
        for (var i = 0; i < tekstarr.length; i++)
        {
            safearr.push(toupper? safe.quoted_sql_upper(tekstarr[i]) : safe.quoted_sql(tekstarr[i]))
        }
        return safearr.join(", ");
    },
    filename: function (naam) // geen 'lage' karakters een geen (back)slashes, *,%,<,>, '"', ':', '?' and '|'
    {
        return naam.replace(/[\x00-\x1F|\/|\\|\*|\%\<\>\"\:\;\?\|]+/g, "_"); // " syntax highlight correctie
    },
    // Altijd quotes er om, we verdubbelen interne
    // CR+LF binnen een waarde maken we alleen LF van
    csv: function (waarde)
    {
        if (waarde==null)
            return "";
        return "\"" + String(waarde).replace(/\x0D\x0A/g,'\x0A').replace(/\"/g,'""') + "\"";  // " syntax highlight correctie
    },
    url: function (s)
    {
        return unescape(encodeURIComponent(escape(s||""))).replace(/\+/g, "%2B");
    }
}

function Hexify(p_path)
{
    var oStream = new ActiveXObject("ADODB.Stream");
    oStream.charset = "Windows-1252";
    oStream.Open();
    oStream.Type = 2; // adTypeText

    oZIP = new ActiveXObject("SLNKDWF.Zip");
    oZIP.FileToHexStream(p_path, oStream);

    oStream.Position = 0;
    ReadBytes = 131072; // optimaal volgens http://support.microsoft.com/kb/280067
    var result = "";
    while (!oStream.EOS)
    {
        result = result + oStream.ReadText(ReadBytes);
    }

    return result;
}

function Base64fy(p_filename)
{
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var base64="";
    if (fso.FileExists(p_filename))
    {
        var bytes = ReadBinaryFile(p_filename);
        var base64 = encodeBase64(bytes);
    }
    else
    {
        __Log("Cannot find file.");
    }
    return base64;
}

function ReadBinaryFile (p_filename)
{
    var oStream = new ActiveXObject("ADODB.Stream");
    oStream.Open();
    oStream.Type = 1; // adTypeBinary
    oStream.LoadFromFile(p_filename);
    return oStream.Read;
}

function encodeBase64(p_bytes){
  var l_xml=new ActiveXObject("Msxml2.DOMDocument.6.0");
  // Create temporary node with Base64 data type
  var xml_element = l_xml.createElement("tmp");
  xml_element.dataType = "bin.base64";
  // Set bytes, get encoded String
  xml_element.nodeTypedValue = p_bytes
  var encodeBase64 = xml_element.text
  return encodeBase64;
}

function jwt_encode(claim, secret)
{
    var header =
    {
      "typ":"JWT",
      "alg":"HS256"
    };

    claim.ver = "1.0";
    var oCrypto = new ActiveXObject("SLNKDWF.Crypto");

    var sheader   = oCrypto.base64(JSON.stringify(header, false)); // no padding
    var sclaim    = oCrypto.base64(JSON.stringify(claim, false));
    var signature = oCrypto.hex_hmac_sha256(secret, sheader + "." + sclaim);
    var sig64     = oCrypto.hex2base64(signature, false, true); // no padding, urlsafe
    var jwt       = sheader + "." + sclaim + "." + sig64;

    return jwt;
}

// Kopie van APPL\AUT\Login.inc
function getBearerToken(prs_key, idp_code, duration)
{
    var sql = "SELECT aut_idp_audience"
            + "     , aut_idp_issuer"
            + "     , aut_idp_secret"
            + "     , aut_idp_duration"
            + "  FROM aut_idp"
            + " WHERE aut_idp_code = " + safe.quoted_sql_upper(idp_code);
    var oRs = Oracle.Execute(sql);
    // logisch? if (oRs("aut_idp_duration").Value)
    duration = Math.min(oRs("aut_idp_duration").Value, duration || 30);
    var iat = Math.round(new Date().getTime() / 1000);
    var exp = iat + duration;

    var claim =
    {
        iat: iat,
        exp: exp,
        jti: "#" + prs_key + "#" + String(new Date().getTime()),
        aud: oRs("aut_idp_audience").Value,
        iss: oRs("aut_idp_issuer").Value,
        perslid_key: prs_key,
        ver: "1.0"
    }
    var jwt = jwt_encode(claim, oRs("aut_idp_secret").Value);
    oRs.Close();

    return jwt;
}