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


//严格模式
/*-------------------------------------------------------------------------------------------*/	
'use strict';
var mysql=require('mysql')
/*-------------------------------------------------------------------------------------------*/

// 过滤的操作
/*-------------------------------------------------------------------------------------------*/	
class filter
{
	static xss(html)
	{
		var arr=['on','expression','script','meta','link']
		var re=/(\<[^\<]+\>)/gi;
		var res;
		while(res=re.exec(html))
		{
			for (const val of arr) 
			{
				res[1]=res[1].replace(val,'deny');
			}
			html=html.replace(res[0],res[1]);
		}
		html=html.replace(/\{%/g,'{ %').replace(/%\}/g,'% }');
		return html;
	}

	static href(str)
	{
		back=back?back:'$M.href';
		return str.replace
		(
			/<a ([\s\S]*?)\shref=(['"])(.*?)\2(.*?>)/,
			'<a $1 onclick="'+back+'(\'$3\')" $4'
		)
	}
	
	static escape(sql_str) 
	{
		if(isNaN(sql_str))return sql_str.replace(/(['|"|\\|\`])/g,'\\$1');
		return sql_str
		//return mysql.escape(sql_str);
	}

	static insert(data,_arr,v,asc,mongo,insert)
	{
		asc=(asc===undefined)?v:asc;
		if(asc===undefined)return;
		if(insert!==undefined)
		{
			_arr[asc]=data[v]
			return
		}
		if(mongo)
		{
			for (const key in data[v]) 
			{
				if(_arr[asc])
				{
					if(_arr[asc][key])
					{
						if(Array.isArray(_arr[asc][key]))_arr[asc][key].push(data[v][key])
						else _arr[asc][key]=[_arr[asc][key],data[v][key]]
					}
					else
					{
						_arr[asc][key]=data[v]
					}
				}
				else _arr[asc]=data[v]
			}
		}
		else if(_arr[asc])
		{
			if(Array.isArray(_arr[asc]))_arr[asc].push(data[v])
			else _arr[asc]=[_arr[asc],data[v]]
		}
		else _arr[asc]=data[v]
	}

	static ['eval'](data={},match={},bool={})
	{
		let code=$Code.sys.field.code
		let globalTag=$Code.sys.field.message
		if(typeof data != 'object')
		{ 
			$Sys.err ({message:"没有传入参数"});
		};
		data={...data}

		let v,_tag;
		let tagMap={}
		let _arr={};
		let _arr1={};
		let objGlobal={}


		for(v in match)
		{
			let cur=match[v]
			if(cur===undefined)$Sys.err({message:`[过滤器${v}]不能为undefined`,code});
			if(data[v]===undefined || data[v]===null)
			{
				if(cur['default']!==undefined)
				{
					data[v]=(cur['default']!==undefined)?cur['default']:'';
				}
				else if(cur['delete'])
				{
					continue;
				}
				else
				{
					$Sys.err({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'未提交'):globalTag),code});
				}
			}
			if(cur['hide'])
			{
				if(data[v])data[v]=cur['default']
			}
			else
			{
				if(cur['reg'])
				{
					if(!cur['reg'].test(data[v]))
					{
						if(cur['delete'])continue;
						$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'当前格式不符合要求'):globalTag),code});
					}             
				}
				else if(cur['number'])
				{
					if(data[v]==='' || data[v]===null || isNaN(Number(data[v])))
					{
						if(cur['delete'])continue;
						$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'需要为数字'):globalTag),code});
					}        
					if(cur['max'])
					{
						if(!(data[v]<=cur['max']))
						{
							if(cur['delete'])continue;
							$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'最大'+cur['max']):globalTag),code});
						}                
					}
					if(cur['min'])
					{
						if(!(data[v]>=cur['min']))
						{
							if(cur['delete'])continue;
							$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'最小'+cur['min']):globalTag),code});
						}                
					}   
					cur['number']=Number(cur['number'])     
				}
				else if(cur['len'])
				{
					if(!(data[v].length==cur['len']))
					{
						if(cur['delete'])continue;
						$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'只能为'+cur['len']+'字符'):globalTag),code});
					}                   
				}
				else
				{
					if(cur['minLen'])
					{
						if(!(data[v].length>=cur['minLen']))
						{
							if(cur['delete'])continue;
							$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'最短'+cur['minLen']+'字符'):globalTag),code});
						}                
					}
					if(cur['maxLen'])
					{
						if(!(data[v].length<=cur['maxLen']))
						{
							if(cur['delete'])continue;
							$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'最长'+cur['maxLen']+'字符'):globalTag),code});
						}                   
					}
				}
				if(cur['escape'])
				{
					data[v]=filter.escape(data[v]);               
				}
				else if(cur['escape']===undefined && (($DbPg.$info.able || $DbMysql.$info.able) && !$DbMongo.$info.able))
				{
					data[v]=filter.escape(data[v]);
				}
				if(cur['xss'])
				{
					data[v]=data[v]=filter.xss(data[v]);        
				}
				if(cur['href']!==undefined)
				{
					data[v]=filter.href(data[v],cur['href']);        
				}
				if(cur['json'])
				{
					try 
					{
						if(cur['json'] instanceof String)
						{
							data[v]=data[v].split(cur['json'])
						}
						else
						{
							data[v]=JSON.parse(data[v])
						}
					} 
					catch (error) 
					{
						$Sys.err ({message:cur['mes']?cur['mes']:($Config.debug?('参数:'+v+'不是一个可json的格式'):globalTag),code});
					}
				}
			}
			if(cur['mongo'])
			{
				data[v]=require('mongodb').ObjectID(data[v]);        
			}
			if(cur['gid'])
			{
				if(cur.detail)data[v]=$Sys.gid(cur.time,cur.pad,cur.tag);      
				else data[v]=$Sys.gid(cur.time,cur.pad,cur.tag).unis;      
			}
			if(cur['fun'])
			{
				let result=cur['fun'](data[v])
				if(result===undefined)
				{
					$Sys.err ({message:globalTag?globalTag:'参数错误',code})
				}
				data[v]=result;
			}
			if(cur['begin'])
			{
				data[v]=cur['begin']+data[v];
			}
			if(cur['end'])
			{
				data[v]+=cur['end'];
			}
			if(cur['handle'])
			{
				if(cur['handle'].indexOf('$')===0)
				{
					_tag=true;
					if(cur['field']===undefined)
					{
						let _key={};
						_key[cur['handle']]=data[v];
						data[v]=_key;
					}
					else
					{
						let _key={};
						_key[v]=data[v];
						if(_arr[cur['handle']])
						{
							_arr[cur['handle']]={..._arr[cur['handle']],..._key};
						}
						else
						{
							_arr[cur['handle']]=_key;
						}
						_tag2=true;
						continue;
					}
				}
				else
				{
					_tag=false;
					data[v]={handle:cur['handle'],value:data[v]}
				}
			}
			if(cur['field']!==undefined)
			{
				filter.insert(data,_arr,v,cur['as'],_tag,true);
				tagMap['field']=true;
			}
			else if(cur['other']!==undefined)
			{
				if(cur['other']===true)cur['other']='other'
				objGlobal[cur['other']]=objGlobal[cur['other']]?objGlobal[cur['other']]:{}
				filter.insert(data,objGlobal[cur['other']],v,cur['as'],_tag);
				tagMap[cur['other']]=true;
			}
			else
			{
				tagMap['where']=true;
				filter.insert(data,_arr1,v,cur['as'],_tag);
			}
			_tag=false;
		}

		for (const key in bool) 
		{
			if(!tagMap[key])$Sys.err ($Code.sys.fieldOver);
		}
		return {field:tagMap.field?_arr:{},where:tagMap.where?_arr1:{},...objGlobal};
	}

	static echo({check=false,message=$Code.sys.check.message,code=$Code.sys.check.code,tag},extend)
	{
		var data={};
		if(check)
		{
			data["code"]=0;
			data["message"]="";
		}
		else
		{
			data["code"]=code;
			data["message"]=message;
		}
		
		data.extend=extend
		data["param"]=check;

		if(!tag && $Config.handle.err)data=$Config.handle.err(data,'echo')
		return data;
	}
}
/*-------------------------------------------------------------------------------------------*/    
module.exports=filter;