
/*=============================================================================================
	author:ZhaoJun
	version:1.2
	email:2732810281@qq.com
=============================================================================================*/


//严格模式
/*-------------------------------------------------------------------------------------------*/	
'use strict';
/*-------------------------------------------------------------------------------------------*/
    
// 复用的操作
/*-------------------------------------------------------------------------------------------*/	
    class com
    {
		static eval (d,render,unique) 
		{
			'use strict';
			render=render||{};
			var du=unique?unique:d;
			try 
			{
				if($Config.compile.has(du))
				{
					let obj=$Config.compile.get(du);
					obj.time=Date.now()
					$Config.compile.set(du,obj)
					return obj.fun(render);
				}
				else
				{
					var da='async function _exec($Rd){'+d+'};var _str_=_exec($Rd);$Config.compile.set($Body,{fun:_exec,time:Date.now()});return _str_;'
					return (new Function('$Rd','$Body',da))(render,du)
				}	
			} 
			catch (error) 
			{
				console.error('脚本执行错误：['+d+']',error);
			}
		}

		static vm(script,sandbox={},opt={timeout:2000})
		{
			let vm=require('vm')
			if(opt.cache)
			{
				let uni=opt.$unique?opt.$unique:script
				if($Config.compileVm.has(uni))
				{
					script=$Config.compileVm.get(uni)
					script.time=Date.now()
				}
				else 
				{
					script = new vm.Script(script);
					$Config.compileVm.set({fun:script,time:Date.now()})
				}
			}
			else script = new vm.Script(script);
			script.runInNewContext(sandbox,opt);
			return sandbox
		}

		static uniObj(obj)
		{
			if(obj instanceof Object)
			{
				let uni=Object.keys(obj).sort()
				let unique=''
				for (const iterator of uni) 
				{
					unique+='&'+iterator+'='+obj[iterator]
				}
				return unique.slice(1)
			}
			else
			{
				return ''
			}
		}

		static promise(fun)
		{
			function cal(resolve,reject)
			{
				fun(resolve,reject)
			}
			return new Promise(cal);
		}

		//应该是定期删除缓存代码，
		static unEval(count,time=3600000)
		{
			if(count%900000!=800000)
			{
				return;
			}
									
			let object=$Config.compile.get(str);
			for (const iterator of object) 
			{
				if((Date.now()-iterator.time)>time)
				{
					$Config.compile.delete(str)
				}
			}
		}

		static hex2int(hex) 
		{
			var len = hex.length, a = new Array(len), code;
			for (var i = 0; i < len; i++) 
			{
				code = hex.charCodeAt(i);
				if (48<=code && code < 58) 
				{
					code -= 48;
				} 
				else 
				{
					code = (code & 0xdf) - 65 + 10;
				}
				a[i] = code;
			}
			
			return a.reduce(function(acc, c) {
				acc = 16 * acc + c;
				return acc;
			}, 0);
		}

		static is32Bit()
		{
			return c.codePointAt(0) > 0xFFFF;
		}
		
		static  toUnicode(data)
		{
			if(data == '' || typeof data == 'undefined') return '请输入字符串';
			let arr=Array.from(data)
			for(var i=0;i<arr.length;i++)
			{
				arr[i]=arr[i].codePointAt()
			}
			return arr
		}
		
		static getUnicode(data)
		{
			if(!Array.isArray(data)) return '请输入十六进制unicode';
			for(var i=0;i<data.length;i++)
			{
				data[i]=String.fromCharCode(data[i]);
			}
			return data.join('');
		}
		
		
        static async sleep(time=50)
        {
			let tr=new Promise
			(
				(reslove,reject)=>
				{
					setTimeout
					(
						function()
						{
							reslove(true);
						},time
					).unref();
				}
			);
            return tr;
		} 


		//每con最多执行num条任务处理
		static async task(list=[],fun,con=1000,num=5)
		{
			while (true) 
			{
				let cur=[]
				let iterator
				while (iterator=list.shift()) 
				{
					cur.push
					(
						new Promise
						(
							function(reslove)
							{
								fun(reslove,iterator)
							}
						)
					) 
					if(cur.length==num)break
				}
				
				let date=Date.now()
				await $Sys.race(Promise.all(cur),3000,'列表任务处理超时')
				date=date-Date.now()-con
				if(date<0)await com.sleep(Math.abs(date))
			}
		}
		
		//用于处理，定时清理的任务，数组里的元素类型为函数
		//arr格式为[时间或其他,函数]
		static interval(time=$Time.interValue)
		{
			function sum(type=' ')
			{
				var table=
				{
					'm':1000*60*60*24*31,
					'd':1000*60*60*24,
					'h':1000*60*60,
					'i':1000*60,
				}
				return table[type.charAt(type.length - 1)]
			}
			setInterval
			(
				function()
				{
					for (const iterator of $Time.task) 
					{
						if(iterator.type=='format' && !iterator.exec && $Sys.model('/tool/time','format',[iterator.init])==iterator.match)
						{
							iterator.timeout=iterator.timeout?iterator.timeout:( sum(iterator.init) )
							iterator.exec=true
							iterator.fun && iterator.fun()
							setTimeout
							(
								function()
								{
									iterator.exec=false
								},iterator.timeout
							)
						}
						else if(iterator.type=='ms')
						{
							if(iterator.init>iterator.match)
							{
								iterator.fun && iterator.fun()
								iterator.init=0
							}
							else
							{
								iterator.init=iterator.init+time
							}
						}
					}
				},time
			)
		}

		//开多少个任务，同时跑。用于异步
		static async round(sup,fun) 
		{
			if(!(fun instanceof Function))
			{
				return;
			}

			async function task(i)
			{
				while(true)
				{
					let result=await 
					(
						new Promise
						(
							(res,rej)=>
							{
								fun(res,rej,i)
							}
						)
					)
					if(result===true)
					{
						return;
					}
				}
			}

			for (let i=0;i<sup;i++) 
			{
				task(i);
			}
		}	

		static async queue({list=[],fun})
		{
			if(!(list instanceof Array) && !(fun instanceof Function))
			{
				return;
			}

			let val;
			while(val=list.shift())
			{
				await 
				(
					new Promise
					(
						(res,rej)=>
						{
							fun(val,res,rej)
						}
					)
				)
			}
		}
		
		static crc16(ptr)
		{
			const _crc16=[ 
				0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,  
				0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,  
				0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,  
				0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,  
				0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,  
				0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,  
				0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,  
				0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,  
				0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,  
				0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,  
				0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,  
				0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,  
				0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,  
				0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,  
				0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,  
				0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,  
				0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,  
				0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,  
				0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,  
				0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,  
				0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,  
				0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,  
				0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,  
				0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,  
				0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,  
				0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,  
				0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,  
				0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,  
				0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,  
				0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,  
				0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,  
				0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0  
			];//crc16表
			var crc = 0x0000;  
			const str=Buffer.from(ptr);
			for (let i = 0; i < str.byteLength; i++) 
			{
				crc =  _crc16[((crc>>8) ^ str[i])] ^ ((crc<<8) & 0x00FFFF);
			}   
			return crc; 
		}
		
    	static sha1(data)
    	{
			var crypto = require('crypto');
    		return crypto.createHash('sha1').update(data,'utf8').digest('hex');
    	}

    	static enAes(data,key=$Config.tokenPass,val=$Config.tokenIv)
    	{
			var crypto = require('crypto');
			var cr=crypto.createCipheriv('aes-128-cbc',key,val);
    		return cr.update(data,'utf8','base64')+cr.final('base64');
    	}

    	static deAes(data,key=$Config.tokenPass,val=$Config.tokenIv)
    	{
			var crypto = require('crypto');
			var cr=crypto.createDecipheriv('aes-128-cbc',key,val);
    		return cr.update(data,'base64','utf8')+cr.final('utf8');
    	}	
    }
/*-------------------------------------------------------------------------------------------*/    
module.exports=com;