/**
 * 判断是否是异步函数
 * @param func 
 * @returns 
 */
export function isFunctionAsync(func:any) {
  if(!isDefined(func))return false;
  return func.constructor.name === 'AsyncFunction';
}
/**
 * 判断是否是函数
 * @param func 
 * @returns 
 */
export function isFunction(func:any) {
  if(!isDefined(func))return false;
  return func.constructor.name === 'Function';
}
/**
 * 判断变量是否定义
 * @param variable 
 * @returns 
 */
export function isDefined<T>(variable: T | undefined): variable is T {
  return variable !== undefined;
}

/**
 * 是否在浏览器里面
 */
export function isExtension():boolean{
  return isDefined(chrome)&&isDefined(chrome.runtime)?true:false;
}
/**
 * 判断是否在background.js执行
 * @returns 
 */
export function isBackgroundScript():boolean{
  if(!isExtension())return false;
  return (chrome.tabs&&!isFunction(chrome.extension.getBackgroundPage))?true:false;
}

/**
 * 判断是否在background.js执行
 * @returns 
 */
export function isPopupScript():boolean{
  if(!isExtension())return false;
  return (chrome.tabs&&isFunction(chrome.extension.getBackgroundPage))?true:false;
}

/**
 * 判断是否在background.js执行
 * @returns 
 */
export function isContentScript():boolean{
  if(!isExtension())return false;
  return chrome.tabs?false:true;
}
/**
 * 
 * @param value 
 * @returns 
 */
export function isString(value:any) {
  return Object.prototype.toString.call(value) === "[object String]";
}
/**
 * 判断是否是对象或者数组
 * @param {*} source
 */
export function isObjectOrArray(source:any) {
  var type = Object.prototype.toString.call(source);
  var res = type === '[object Array]' || type === '[object Object]';
  return res;
}
/**
* 判断是否是对象
* @param {*} source
*/
export function isObject(source:any) {
  var type = Object.prototype.toString.call(source);
  var res = type === '[object Object]';
  return res;
}
/**
* 判断是否是数组
* @param {*} source
*/
export function isArray(source:any) {
  var type = Object.prototype.toString.call(source);
  var res = type === '[object Array]';
  return res;
}
/**
 * 判断是否在node环境
 * @returns 
 */
export function isNodeEnvironment(): boolean {
  return (typeof process !== 'undefined' && process.versions && process.versions.node)?true:false;
}
/**
 * 获取运行环境
 * @returns 
 */
export function getEnv():string{
  if(isNodeEnvironment()){
    return 'node'
  }
  if(isBackgroundScript()){
    return 'background'
  }
  if(isContentScript()){
    return 'content'
  }
  if(isPopupScript()){
    return 'popup'
  }
  return ''
}
/**
 * 判断是否为Promise
 * @param value 
 * @returns 
 */
export function isPromise( value:any ):boolean {
	return !!value
		&& (typeof value === 'object' || typeof value === 'function')
		&& typeof value.then === 'function';
}
/**
 * 生成唯一id
 * @returns 
 */
export function guid() {
  return 'xxxxxxxx-xxxx-8xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      var r = Math.random() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
  });
}