/**
 * 由于ajax的jsonp请求以script标签的方式，普通的监控方法无法捕捉到jsonp中的响应值，这里需要手动上报
 */
(function($){

    // 获取接口名
    function getAction(url){
        return url.substring(0, url.indexOf("?")).replace('http://', '').replace('https://', '').replace('//', '');
    }

    // 格式化响应体
    function formatBody(str){
        if( typeof str === 'object'){
            return str;
        }
        try{
            return JSON.parse(str);
        }catch(e){
            return str;
        }
    }

    // 需要排除的返回码：成功码 0
    function isOmitCode(opts){
        // 不是规范的响应体，按照成功返回
        if(typeof opts.body !=='object'){
            return true;
        }
        // 由于各个接口模块的规范不统一，此处需要增量记录返回码code的字段映射
        var list = ['result','RetCode', 'ret', 'SeedRet'];
        var body = opts.body;
        for(var i=0; i<list.length; i++){
            var code = body[list[i]];
            if(typeof code !== 'undefined'){
                opts.code = code; // 添加 code, 方便后续统计
                if(code === 0){
                    return true;
                }
            }
        }
        return false;
    }

    // 需要排除的请求：点击上报
    function isOmitUrl(opts){
        if(typeof opts.action ==='undefined'){
            return false;
        }
        var list = [
            'log.minigame.qq.com',
            'dir.minigame.qq.com/cgi-bin/QQGame_MyGame/dir_tlog',
            'dir.minigame.qq.com/cgi-bin/QQGame_MyGame/dir_tlog_no_skey'
        ]
        var action = opts.action;
        for(var i=0; i<list.length; i++){
            if(action.indexOf(list[i]) > -1){
                return true;
            }
        }
        return false;
    }

    // 上报Api请求
    function reportApi(opts, onReport) {

        if (isOmitUrl(opts)) {
            return true;
        }

        // 处理返回码
        if(
            typeof opts.event !== 'undefined' &&
            opts.event === 'http-success' &&
            !isOmitCode(opts)
        ){
            onReport(opts, 'retError');
            return false;
        }

        onReport(opts);
        return true;
    }

    // 初始化window.onerror事件
    function initWinError(onReport){
        // catch global error and report
        window.onerror = function (message, url, line, column, error) {
            if(error){
                var stack = error.stack;
                stack = stack.split(/\r?\n/g);
                stack = stack.join('\n');
                var data = {
                    event: 'client-error',
                    action: getAction(location.href),
                    message: arguments[4].message, 
                    stack: stack
                }
                onReport(data, 'error');
            } else {
                // because of cross domain, normally we just get "Script error", 
                // we don't know soure url and line and column.
                // but we still need to know there was an error on our page.
                onReport({
                    event: 'client-error',
                    message: message,
                    action: getAction(url),
                    line: line || 0, 
                    column: column || 0,
                    stack: new Error().stack
                }, 'error');
            }
        }

        onReport({
            event: 'client-html',
            action: getAction(location.href),
        });

    }

    function initJSON(onReport) {
        // 上报jquery的ajax请求
        $(document).ajaxComplete(function(event, jqXHR, ajaxOptions) {
            // 使用了json请求的js，也直接返回
            if(getAction(ajaxOptions.url).indexOf('.js') > -1){ return;}

            var p = {
                event: 'http-success',
                action: getAction(ajaxOptions.url),
                url: ajaxOptions.url || '',
                body: formatBody(jqXHR.responseText),
                method: ajaxOptions.type || 'GET',
                reqBody: ajaxOptions.data || '',
                code: 0 // 利用对象引用的特性，此code的值会被reportApi方法修改
            }
            reportApi(p, onReport);
        });
    }

    function initJSONP(onReport){
        // 上报jquery的jsonp请求
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                var origCallback = settings.jsonpCallback;
                // 如果不是jsonp请求，则直接返回，不做任何处理
                if (!origCallback || typeof origCallback !== 'string') { return; }
                // 使用了jsonp请求的js，也直接返回
                if(getAction(settings.url).indexOf('.js') > -1){ return;}

                settings.url = settings.url.replace(/=jQuery/, "=jquery");
                reportApi({ event: 'http-start', type: 'jsonp', action: getAction(settings.url), url: settings.url }, onReport);
                window[origCallback.toLowerCase()] = function(origCallback, settings) {
                    return function() {
                        var opts = { 
                            event: 'http-success',
                            type: 'jsonp',
                            action: getAction(settings.url),
                            url: settings.url,
                            body: formatBody(arguments[0]),
                            method: 'GET',
                            code: 0 // 利用对象引用的特性，此code的值会被reportApi方法修改
                        };
                        reportApi(opts, onReport);
                        if(typeof window[origCallback] === 'function'){
                            window[origCallback].apply(this, arguments);
                        }
                    }
                }(origCallback, settings);
            }
        });
    }

    window.reportAjax = {
        init: function(){ // 主页面使用此方法初始化
            if(!$){ return; }
            if(typeof window.gAegis === 'undefined') { return; }
            var handle = function(opts, type){
                // console.info('init', opts);
                if(typeof window.gAegis !== 'undefined') {
                    var str = opts;
                    if( typeof str === 'object'){
                        str = JSON.stringify(str);
                    }
                    if(typeof window.gAegis[type] !== 'undefined'){
                        window.gAegis[type](str);
                    } else {
                        window.gAegis.infoAll(str);
                    }
                }
            }
            initJSON(handle);
            initJSONP(handle);
        },
        initIframe: function(){ // iframe页面使用此方法初始化
            if(!$) return;
            if(typeof window.GameAPI === 'undefined' || typeof window.GameAPI.ReportMonitor === 'undefined'){
                return;
            }
            function handle(opts, type){
                if(typeof window.GameAPI !== 'undefined' && typeof window.GameAPI.ReportMonitor !== 'undefined') {
                    window.GameAPI.ReportMonitor(opts, type);
                }
            }
            initWinError(handle);
            initJSON(handle);
            initJSONP(handle);
        }
    }

    // 获取appid
    function getUrlParam(key) {
        var reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)');
        var r = window.location.search.substr(1).match(reg);
        if (r !== null) return String(unescape(r[2]));
        return '';
    }
    // 预定义通用参数
    var preReportParam = { 
        pay: { field1: 2021031001},
        pagePerformance: { field1: 2021031501},
    };
    function reportTLog(data, type) {
        if(typeof type !== 'undefined' && typeof preReportParam[type] !== 'undefined'){
            $.extend(data, preReportParam[type]);
        }
        var fields = (function () {
            var param = {};
            for (var i = 0; i < 26; i++) {
                param['field' + i] = -1;
                if (data['field' + i] || data['field' + i] == 0) param['field' + i] = data['field' + i];
            }
            return param;
        })();

        var rData = $.extend(fields, {
            structname: 'webCommonReport',
            fieldcount: 26,
            field0: 40034,
            field7: getUrlParam('appid')
        });
        // console.log(JSON.stringify(rData));
        // 米大师支付窗口以及开通蓝钻窗口上报一份到aegis
        if(type === 'pay' && typeof window.gAegis !== 'undefined') {
            gAegis.reportEvent(rData.field16 === 1 ? 'midas-pay' : 'openvip-pay');
        }

        $.ajax({
            url: '//log.minigame.qq.com/cgi-bin/dir_tlog',
            dataType: 'jsonp',
            data: rData
        });
    };
    //经分数据上报
    window.gReportTLog = reportTLog;


    // 定义一个页面的开始时间，方便页面没有定义window.gAegisStartTime时，进行兜底
    var pageStartTime = new Date().getTime();

    // 获取框架页面标记的开始时间，一般在主框架页面最开始的位置记录当前的时间 new Date().getTime()
    function getFrameStartTime(){
        var time =  window.gAegisStartTime || pageStartTime;
        return time;
    }

    // 上报指标和当前时间戳
    function ReportTTime(name, pCurTime){
        var curTime = pCurTime || new Date().getTime();

        // 页面的性能时长上报到Aegis
        if(typeof window.gAegis !== 'undefined') {
            var time = getFrameStartTime();
            if(time > 0){
                var costTime = curTime - time;
                gAegis.reportTime('web_' + name,  costTime);
            }
        }

    };
    // 经分耗时数据上报，同时上报一份到Aegis
    window.gReportTime = ReportTTime;

})($);

