(function errorListenerFn(win, doc) {
    var errorData, token;

    function getUrlParams(key) {
        var query, vars, pair, i;

        query = win.location.search.substring(1);
        vars = query.split('&');
        for (i = 0; i < vars.length; i += 1) {
            pair = vars[i].split('=');
            if (pair[0] === key) {
                return pair[1];
            }
        }

        return '';
    }

    function isPreLoad() {
        var type = getUrlParams('type');

        if (type === 'preload') {
            return true;
        }

        return false;
    }

    function isCacheLoad() {
        var type = getUrlParams('type');

        if (type === 'cache') {
            return true;
        }

        return false;
    }

    function isNull(str) {
    	return str === null;
    }

    function isUndefined(data) {
        return typeof data === 'undefined';
    }

    function isString(str) {
        return typeof str === 'string';
    }

    function isEmptyString(str) {
        if (isUndefined(str) === true || isString(str) === false) {
            return false;
        }

        return str.length === 0;
    }

    function isEmpty(data) {
    	return isNull(data) === true || isEmptyString(data) === true ||
				isUndefined(data) === true;
    }

    function getErrorMsg() {
        var msg = null;

        if (isEmpty(errorData) === false) {
            if (
                isEmpty(errorData.error) === false &&
                isEmpty(errorData.error.stack) === false
            ) {
                msg = errorData.error.stack;
            }
            else if (
                isEmpty(errorData.error) === false &&
                isEmpty(errorData.error.message) === false
            ) {
                msg = errorData.error.message;
            }
            else if (isEmpty(errorData.message) === false) {
                msg = errorData.message;
            }
            else {
                msg = errorData;
            }
        }
        else if (isEmpty(errorData) === true || isEmpty(msg) === true) {
            msg = 'error.msg.is.empty.in.errorlistener';
        }

        return msg;
    }

    function handleErrorForHeadlessService() {
        var errorMsg = {}, msg;

        msg = getErrorMsg();
        errorMsg.message = msg;

        return JSON.stringify(errorMsg);
    }

    // if function not available 
    if (!(typeof win.getPreLoadErrors === 'function')) {
    	win.getPreLoadErrors = function getPreLoadErrorsFunc() {
	        return new Promise(function applyFn(resolve, reject) {
	        	var value;

                console.log('getPreLoadErrors.from.errorlistener');
                try {
                    value = handleErrorForHeadlessService();
                }
                catch (err) {
                    reject(err);

                    return;
                }
                resolve(value);
	        });
	    };
    }

    if (isPreLoad() === true || isCacheLoad() === true) {
    	win.addEventListener('error', function error(errordetail) {
    		errorData = errordetail;
            token = getUrlParams('token');
    		console.log('preload.error.' + token); // dont remove this, use in headlessService
    		console.log('preload.error.from.error.listener.js');
    	});

        doc.body.addEventListener(
            'preloadErrorFromApp', function onPreloadError(preloadEvent) {
                errorData = preloadEvent.detail.errorData;
        },
        false);
    }
})(window, document);
