/*



*/

// ----------------------------------------------------------------------
// CONSTANTS
// ----------------------------------------------------------------------

const AM_RESULTS={
    0: 'OK',
    1: 'unknown',
    2: 'warning',
    3: 'error'
};

const OUT_ID_APPS='app-section';
const OUT_ID_TAGS='tag-section';
const ID_TAGINPUT='E_TAGS';

// ----------------------------------------------------------------------
// VARS
// ----------------------------------------------------------------------

var AM_TAGURL=false;
var AM_PRETTYURL=false;
var AM_TIMER=false;

// ----------------------------------------------------------------------
// FUNCTIONS
// ----------------------------------------------------------------------

function _getAMApiUrl(sPath){
    return AM_PRETTYURL 
        ? AM_SERVER_URL+sPath
        : AM_SERVER_URL+'/index.php?request='+sPath
    ;
}

/**
 * get url to fetch the tags
 * @returns string
 */
function _getUrlForTags(){
    return  _getAMApiUrl('/v1/apps/tags');
}

/**
 * get url to fetch all applications with given tags
 * @param {string} tags list of tags - separated by comma
 * @returns 
 */
function _getUrlWithTags(tags){
    return  _getAMApiUrl('/v1/apps/tags/'+tags+'/all');
    }

/**
 * helper: get a table row with data of an application
 * @param {string} sLabel 
 * @param {string} sText 
 * @returns string
 */
function _appItem(sLabel,sText){
    return '<tr><td>'+sLabel+'&nbsp;&nbsp;</td><td>'+sText+'</td></tr>'
}

/**
 * helper: get a 2 digit count
 * @param {int} i 
 * @returns 
 */
function _2digits(i){
    return i<10 ? "0"+i : i;
}

// ----------------------------------------------------------------------
// FUNCTIONS :: TAGS
// ----------------------------------------------------------------------


function tagToggle(tagname){
    var o=document.getElementById(ID_TAGINPUT);
    var s=o.value;
    var re = new RegExp(",*"+tagname);
    var s2=s.replace(re, "");
    if(s2!==s) {
        s=s.replace(re, "")
        s=s.replace(/^,/, "");
    } else {
        s+=(s ? "," : "" ) + tagname;
    }
    o.value=s;
    getAppstatus();
}

function tagClear(){
    var o=document.getElementById(ID_TAGINPUT);
    o.value="";
    getAppstatus();
}

/**
 * called from getTags
 * @param {string} sData JSOM Response
 * @returns 
 */
function _getTaglist(sData){
    var sReturn='';
    var sTags='';
    let aData=JSON.parse(sData);

    // sReturn+='<code>'+sData+'</code><br>';
    sReturn+='<input id="'+ID_TAGINPUT+'" type="text" size="20" value="'+AM_TAGS+'"'
            +' onkeypress="getAppstatus()"'
            +' onkeydown="getAppstatus()"'
            +' onkeyup="getAppstatus()"'
        +'>'
        +'<button onclick="tagClear();return false;"> ❌ </button><br>'
        ;

    for (var s in aData['tags']){
        sTags+=(sTags ? ",": "") + aData['tags'][s];
        sReturn+='<button onclick="tagToggle(\''+aData['tags'][s]+'\'); return false;">'+aData['tags'][s]+'</button>'
    }
    return sReturn;
}



/**
 * fetch appmonitor api - taglist
 * called from getAppstatus
 */
 async function getTags(){
    AM_TAGURL=_getUrlForTags();

    let out = '<h2><span>🏷️</span> Tags</h2>';

    try{
        let response = await fetch(AM_TAGURL, { "headers": 
            AM_AUTH 
        } );

        // let response = await fetch(AM_TAGURL);
        if (response.ok) {
            out+=_getTaglist(await response.text());
        } else {
            out+='<div class="app result1">'
                +'ERROR '+response.status+': '+response.statusText + ' - '
                +AM_TAGURL
                +'</div>';
        } 
    } catch {
        out+='<div class="app result1">'
        +'UNKNOWN: no response from '
        +AM_TAGURL
        +'</div>';
    }
    
    o=document.getElementById(OUT_ID_TAGS).innerHTML=out;
}


// ----------------------------------------------------------------------
// FUNCTIONS :: APPS
// ----------------------------------------------------------------------

/**
 * loop over apps and render results as html
 * @param {string}  sData  response body from api request (JSON string)
 * @returns string
 */
function _getAllAppsStatus(sData){
    var sReturn="";
    var oDate=new Date;
    // sReturn+='<code>'+sData+'</code><br>';
    sReturn+=''
            +'<h3>Tags: ' + tags + '</h3>'
            + '<p>' 
            +_2digits(oDate.getHours())
            +':'+_2digits(oDate.getMinutes())
            +':'+_2digits(oDate.getSeconds())
            +' (update every '+REFRESHTIME+' sec)'
        +'</p>';
    let aAllData=JSON.parse(sData);
    for (var key in aAllData){
        sReturn+=_getSingleAppStatus(aAllData[key]);
    }
    return sReturn;
}

/**
 * render application status of a single application as html
 * @param {array} aData monitoring data from appmonitor api
 * @returns string
 */
function _getSingleAppStatus(aData){
    // let aData=JSON.parse(sData);

    // DEBUG
    // console.log(aData);

    // ------ checks
    let sChecks='';
    for (var j=0; j<aData.checks.length; j++){
        let tmpCheck=aData.checks[j];
        sChecks+='<tr class="result'+tmpCheck.result+'">'
            +'<td>'+tmpCheck.name+'</td>'
            +'<td>'+tmpCheck.description+'</td>'
            +'<td>'+tmpCheck.value+'</td>'
            +'</tr>'
            ;
    }
    sChecks=sChecks ? '<table>'+sChecks+'</table>' : ' (No checks were found)';

    // ----- generate output
    let sReturn='<div class="app result'+ aData.meta.result +'">'
        +'<div class="title" onclick="$(this).next().toggle()">'
            +'<span class="float-right">'+AM_RESULTS[aData.meta.result]+'</span>'
            +'<span class="float-right url">'+aData.result.url+'</span>'
            +aData.meta.website
        +'</div>'
        ;

    // age of the result data
    let iAge=Math.round((new Date()).getTime() / 1000)- aData.result.ts;

    sReturn+=''
        +'<table class="details">'
        +_appItem('Summary', 'Application status: '+ AM_RESULTS[aData.meta.result] 
            + ' | Checks: ' + aData.checks.length 
            + ' | Age: ' + iAge + ' sec'
            + ' | TTL: ' + aData.result.ttl 
            )
        +_appItem('Checks', sChecks)
        
        +'</table>'
        ;

    sReturn+='</div>';

    return sReturn;
}

/**
 * fetch appmonitor api - status of apps
 */
async function getAppstatus(){


    var o=document.getElementById(ID_TAGINPUT);
    tags=o ? o.value : AM_TAGS;

    let out = '<h2><span>📦</span> Applications</h2>';
    let apiurl=_getUrlWithTags(tags)
    // let myfunction="_getAllAppsStatus";
    try{
        let response = await fetch(apiurl, { "headers": 
            AM_AUTH 
        } );
        if (response.ok) {

            out+=_getAllAppsStatus(await response.text());
            // out+=eval(myfunction+'(await '+response.text()+')');
            
        } else {
            out+='<div class="app result1">'
                +'ERROR '+response.status+': '+response.statusText + ' - '
                +apiurl
                +'</div>';
        } 
    }
    catch {
        out+='<div class="app result1">'
        +'UNKNOWN: no response from '
        +apiurl
        +'</div>';
    }
    // }
    document.getElementById(OUT_ID_APPS).innerHTML=out;
    clearTimeout(AM_TIMER);
    AM_TIMER=window.setTimeout("getAppstatus()", REFRESHTIME*1000);
}


// ----------------------------------------------------------------------
// MAIN
// ----------------------------------------------------------------------

// for auth header with basic auth
let AM_AUTH=(AM_USER)
    ? { "Authorization": "Basic " + btoa(AM_USER + ":" + AM_PASSWORD) }
    : {}
;

getTags();
AM_TIMER=window.setTimeout("getAppstatus()", 500);


// ----------------------------------------------------------------------