(function(global) {
  "use strict";

  var ERR_MODULE_ID = {
    FED_MODULE_ID_DEFAULT: 1000,

    // Built-in browser page
    FED_MODULE_ID_RESTORE_LAST_TAB: 1001,
    FED_MODULE_ID_DOWNLOADS: 1002,
    FED_MODULE_ID_SETTINGS: 1003,
    FED_MODULE_ID_HISTORY: 1004,
    FED_MODULE_ID_EXTENSIONS_MANAGEMENT: 1005,
    FED_MODULE_ID_NEWTAB: 1006,
    FED_MODULE_ID_INCOGNITO: 1007,
    FED_MODULE_ID_PASSWORD_MANAGEMENT: 1008,

    // Own browser extensions
    FED_MODULE_ID_UC_NEXUS: 2001,
    FED_MODULE_ID_UC_ACTIVITY: 2002,
    FED_MODULE_ID_UC_LARGER_IMAGE: 2003,
    FED_MODULE_ID_UC_BROWSER_ENHANCER: 2004,
    FED_MODULE_ID_UC_VIDOG: 2005,
    FED_MODULE_ID_UC_READER_MODEL: 2006,
    FED_MODULE_ID_UC_PPHELPER: 2007,
    FED_MODULE_ID_UC_BOOKMARK_MANAGER: 2008,
    FED_MODULE_ID_UC_CRICKET: 2009,
    FED_MODULE_ID_UC_ADBLOCK: 2010
  };

  var ERR_CODE_INFO = {
    UnknownError: {
      code: 0,
      des: '未知错误'
    },

    // W3C standard error exception(ErrorEvent)
    EvalError: {
      code: 1,
      des: 'eval()函数错误'
    },
    InternalError: {
      code: 2,
      des: '内部JavaScript引擎错误，可能存在太多递归'
    },
    RangeError: {
      code: 3,
      des: '传递参数或者数值非允许范围'
    },
    ReferenceError: {
      code: 4,
      des: '引用不存在的变量'
    },
    SyntaxError: {
      code: 5,
      des: '语法解析错误'
    },
    TypeError: {
      code: 6,
      des: '类型错误，操作数或参数传递给函数操作符不符合预期的类型或函数'
    },
    URIError: {
      code: 7,
      des: '以错误的方式使用了全局URI处理'
    },

    // Custom error exception
    ScriptLoadFailed: {
      code: 10,
      des: '动态脚本加载失败'
    },
    ImageLoadFailed: {
      code: 11,
      des: '插入图片加载失败'
    },
    DataNullError: {
      code: 12,
      des: '空返回数据，正常不应该为空'
    },
    ServerLoadError: {
      code: 13,
      des: '服务器加载失败'
    }
  };

  global.ERR_MODULE_ID = ERR_MODULE_ID;
  global.ERR_CODE_INFO = ERR_CODE_INFO;
  const ERR_ERROR_EVENT = 'ErrorEvent';
  const ERR_EVENT = 'Event';

  global.wowErrorRecoder = {
    request: function(moduleId, errCode, des) {
      if (chrome.wowPrivate) {
        chrome.wowPrivate.send("recordErrorStats", JSON.stringify({
            module_id : moduleId,
            error_code : errCode,
            data : des
        }));
      }
    },
    sendRecord : function(moduleId, e, customDes) {
      var errTypeInfo = ERR_CODE_INFO['UnknownError'],
          errDesInfo = '';

      if (typeof e === "object") {
        var errName = e.constructor.name;

        if (errName === ERR_ERROR_EVENT) {
          var message = e.message ? e.message : '',
              fileName = e.filename ? e.filename : '';

          errTypeInfo = (e.error && e.error.name) ? ERR_CODE_INFO[e.error.name] : errTypeInfo;
          errDesInfo = (e.error && e.error.stack) ? e.error.stack : `${message};${fileName}`;
        } else if (errName === ERR_EVENT) {
          var tagName = e.target.tagName.toLowerCase();

          if (tagName === 'script') {
            errTypeInfo = ERR_CODE_INFO['ScriptLoadFailed'];
          } else if (tagName === 'img') {
            errTypeInfo = ERR_CODE_INFO['ImageLoadFailed'];
          }
        } else if (ERR_CODE_INFO[errName]) {
          errTypeInfo = ERR_CODE_INFO[errName] ? ERR_CODE_INFO[errName] : errTypeInfo;
          errDesInfo = e.message ? e.message : '';
        }
      } else if (ERR_CODE_INFO[e]) {
        errTypeInfo = ERR_CODE_INFO[e];
      }

      var errCode = errTypeInfo.code,
          des = errDesInfo;

      if (customDes) {
        des = customDes;
      } else if (!des) {
        des = errTypeInfo.des;
      }
      this.request(moduleId, errCode, des);
    }
  }
})((function() {
  if (typeof module === "object" && typeof module.exports==="object") {
    return module.exports;
  }
  return this;
})());