/**
 * Copyright (c) 2020
 *
 * CENTIRM HotelTV Background service module javascript.
 *
 * @summary short description for the file
 * @author Joel <joel.kim@centirm.com>
 *
 * Created at     : 2020-11-26 02:21:56
 * Last modified  : 2020-11-26 15:31:40
 */
// importScripts('./lib/hoteltv.js');
// importScripts('./lib/hoteltv.api.js');

const g_config = {};
var g_port = null;
var g_tmrHndl = null;
var g_tm_prev = {
    "news": null,
    "epg": null,
    "weather": null,
    "widget": null,
    "flight": null,
    "report": null,
};

//// 비공개 매써드
/**
 * API Wrapper Function::>
 */
function __svcfxn_get_base_url() {
    var sz_base_url = "http://" + g_config.svrinfo.ipaddr + ":" + g_config.svrinfo.port;
    return sz_base_url;
}

/**
 * API Wrapper Function::>
 * @param {string} api_type api type.
 * @param {callback} callback is callback object
 */
function __svcfxn_get_api_url(api_type) {
    var dic_api_url = {
        "get_news": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/news",
        "get_epg": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/epg",
        "get_weather": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/weather",
        "get_widget": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/widget",
        "get_flight": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/flight",
    }

    if (api_type in dic_api_url) {
        return dic_api_url[api_type];
    }
    return null;
}

/**
 * API Wrapper Function::> HOTELTV API
 * @param {string} sz_url is API URL
 * @param {string} api_type is API TYPE
 * @param {dictionary} dic_param is PARAMETERs
 */
function __svcfxn_CallCmsApi(sz_url, api_type, dic_param) {
    return new Promise((resolve, reject) => {
        let isPostMsg = false;
        let xhr = new XMLHttpRequest();
        let formData = new FormData();
        let _ret = { type: api_type, error: true, reason: null, data: null };

        //xhr.timeout = 500;
        if (dic_param !== null) {
            isPostMsg = true;
            for (_key in dic_param) {
                formData.append(_key.toString(), dic_param[_key]);
            }
        }

        xhr.onload = function() {
            if (xhr.status === 200 || xhr.status === 201) {
                _ret.error = false;
                _ret.data = xhr.response;
                resolve(_ret);
            } else {
                reject(_ret);
            }
        };

        xhr.ontimeout = function(e) {
            // XMLHttpRequest timed out. Do something here.
            _ret.reason = "TIMEOUT";
            reject(_ret);
        };

        xhr.onerror = function() {
            _ret.reason = "FATAL";
            reject(_ret);
        }


        if (isPostMsg) {
            //console.log("Given api url is POST message")
            xhr.open('POST', sz_url);
            xhr.setRequestHeader("Accept", "application/json");
            xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
            xhr.setRequestHeader("Authorization", "Bearer " + g_config.token.apikey);
            xhr.send(formData); // 폼 데이터 객체 전송
        } else {
            //console.log("Given api url is GET message")
            xhr.open('GET', sz_url, true);
            xhr.setRequestHeader("Accept", "application/json");
            xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
            xhr.setRequestHeader("Authorization", "Bearer " + g_config.token.apikey);
            xhr.send(null);
        }
    });
}



/**
 * HCAP Wrapper Function::> Get Device Properties(Realted HCAP API:hcap.property.getProperty)
 * @param {string} sz_key property key name.
 * @param {callback} callback is callback object
 */
async function sworker_service(args) {
    return new Promise((resolve, reject) => {
        let _bNeed_Update = {
            "epg": false,
            "news": false,
            "flight": false,
            "weather": false,
            "widget": false,
            "report": false,
        };
        let _tm_cur = new Date();


        // CHECK REPORT INFORMATION UPDATE
        if (g_tm_prev.report == null) {
            g_tm_prev.report = new Date();
            _bNeed_Update.report = true;
        } else {
            let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.report.getTime();
            let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);

            //REPORT는 매 5초 마다 한번씩 업데이트
            if (_tm_diff_s > 5) {
                g_tm_prev.report = _tm_cur;
                _bNeed_Update.report = true;

                if (g_tm_prev.epg == null) {
                    g_tm_prev.epg = _tm_cur;
                }

                if (g_tm_prev.news == null) {
                    g_tm_prev.news = _tm_cur;
                }

                if (g_tm_prev.flight == null) {
                    g_tm_prev.flight = _tm_cur;
                }

                if (g_tm_prev.weather == null) {
                    g_tm_prev.weather = _tm_cur;
                }
            }
        }

        // CHECK EPG INFORMATION UPDATE
        if (g_tm_prev.epg != null) {
            let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.epg.getTime();
            let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);

            //EPG정보는 매 30분 마다 한번씩 업데이트
            if (_tm_diff_s > 1800) {
                //if (_tm_diff_s > 60) {
                g_tm_prev.epg = _tm_cur;
                _bNeed_Update.epg = true;
            }
        }

        // CHECK NEWS INFORMATION UPDATE
        if (g_tm_prev.news != null) {
            let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.news.getTime();
            let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);

            //NEWS정보는 매 20분 마다 한번씩 업데이트
            if (_tm_diff_s > 1200) {
                g_tm_prev.news = _tm_cur;
                _bNeed_Update.news = true;
            }
        }


        // CHECK FLIGHT INFORMATION UPDATE
        if (g_tm_prev.flight != null) {
            let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.flight.getTime();
            let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);

            //FLIGHT정보는 매 60분 마다 한번씩 업데이트
            if (_tm_diff_s > 3600) {
                g_tm_prev.flight = _tm_cur;
                _bNeed_Update.flight = true;
            }
        }

        // CHECK WEATHER INFORMATION UPDATE
        if (g_tm_prev.weather != null) {
            let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.weather.getTime();
            let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);

            //WEATHER정보는 매 2시간 마다 한번씩 업데이트
            if (_tm_diff_s > 7200) {
                g_tm_prev.weather = _tm_cur;
                _bNeed_Update.weather = true;
            }
        }

        // CHECK WIDGET INFORMATION UPDATE
        if (g_tm_prev.widget != null) {
            let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.weather.getTime();
            let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);

            //WEATHER정보는 매 1시간 마다 한번씩 업데이트
            if (_tm_diff_s > 3600) {
                g_tm_prev.widget = _tm_cur;
                _bNeed_Update.widget = true;
            }
        }



        // 후처리(실제 데이터 가져오고 부모에세 메시지로 안내)
        if (_bNeed_Update.epg === true) {
            let sz_api_url = __svcfxn_get_api_url("get_epg");
            __svcfxn_CallCmsApi(sz_api_url, "GetEpg", null).then(_result => {
                g_port.postMessage({ "event": "update_epg", "ret": "OK", "data": JSON.parse(_result.data) });
            }).catch(_error => {
                g_port.postMessage({ "event": "update_epg", "ret": "ERROR", "data": null });
            });
        }

        if (_bNeed_Update.news === true) {
            let sz_api_url = __svcfxn_get_api_url("get_news");
            __svcfxn_CallCmsApi(sz_api_url, "GetNews", null).then(_result => {
                g_port.postMessage({ "event": "update_news", "ret": "OK", "data": JSON.parse(_result.data) });
            }).catch(_error => {
                g_port.postMessage({ "event": "update_news", "ret": "ERROR", "data": null });
            });
        }

        if (_bNeed_Update.flight == true) {
            let sz_api_url = __svcfxn_get_api_url("get_flight");
            __svcfxn_CallCmsApi(sz_api_url, "GetFlight", null).then(_result => {
                g_port.postMessage({ "event": "update_flight", "ret": "OK", "data": JSON.parse(_result.data) });
            }).catch(_error => {
                g_port.postMessage({ "event": "update_flight", "ret": "ERROR", "data": null });
            });
        }

        if (_bNeed_Update.weather == true) {
            let sz_api_url = __svcfxn_get_api_url("get_weather");
            __svcfxn_CallCmsApi(sz_api_url, "GetWeather", null).then(_result => {
                g_port.postMessage({ "event": "update_weather", "ret": "OK", "data": JSON.parse(_result.data) });
            }).catch(_error => {
                g_port.postMessage({ "event": "update_weather", "ret": "ERROR", "data": null });
            });
        }

        if (_bNeed_Update.widget == true) {
            let sz_api_url = __svcfxn_get_api_url("get_widget");
            __svcfxn_CallCmsApi(sz_api_url, "GetWidget", null).then(_result => {
                g_port.postMessage({ "event": "update_widget", "ret": "OK", "data": JSON.parse(_result.data) });
            }).catch(_error => {
                g_port.postMessage({ "event": "update_widget", "ret": "ERROR", "data": null });
            });
        }

        if (_bNeed_Update.report == true) {
            g_port.postMessage({ "event": "update_report", "ret": "OK", "data": _bNeed_Update.report });
        }
        resolve();
    });
};














onconnect = function(e) {
    if (g_port != null) {
        return;
    }

    g_port = e.ports[0];

    g_port.addEventListener('message', function(e) {
        let recvMsg = e.data;
        if (recvMsg.cmd === "start_service") {
            let _param = recvMsg.param;
            g_config.token = _param.token;
            g_config.dev_family = _param.dev_family;
            g_config.dev_snum = _param.dev_snum;
            g_config.svrinfo = _param.svrinfo;

            //Periodic polling HotelTV API service
            if (g_tmrHndl == null) {
                g_tmrHndl = setTimeout(async function svcTask() {
                    await sworker_service();
                    g_tmrHndl = setTimeout(svcTask, 1000);
                }, 0);
            }
        }
    });

    g_port.start(); // Required when using addEventListener. Otherwise called implicitly by onmessage setter.
}