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


//严格模式
/*-------------------------------------------------------------------------------------------*/	
'use strict';
/*-------------------------------------------------------------------------------------------*/
const url = require('url');
const filters= $Sys.model('/fun/filter')

// http操作
/*-------------------------------------------------------------------------------------------*/	
    class init_h
    {
        static async route(request,response)
        {	
        	var _url=url.parse(request.url,true);
			var _path=_url.pathname;

			
			request._cookie=[];
			request.pathname=_path;
			request.query=_url.query?_url.query:{};
			request.get=request.query
			request.post={};
			request.ip= request.connection.remoteAddress ||
			request.socket.remoteAddress ||
			request.connection.socket.remoteAddress || '';
			request.$responseData=''
			
			response.sender=function(data,ty)
			{
				if($Config.debug && request.ip=='127.0.0.1' && request.headers.referer)
				{
					let obj=request[Symbol.for('doc')]
					if(obj)
					{
						if(!obj.fixed)
						{
							let dataMe=data
							if(ty)
							{
								try {dataMe=JSON.parse(data)} catch (error) {}
							}
			
							$Config.loadApi.tag=false
							setTimeout(()=>{$Config.loadApi.tag=true},$Config.loadApi.time)
							$Sys.model('/tool/config/doc','apiBack',[obj.base.group,obj.base.descript,dataMe,obj.descriptParam,obj.requestPath,request.requestMethod,obj])
						}
					}
				}
				if(ty)
				{
					response.headersSent?"":response.setHeader("Content-Type",'application/json; charset=utf-8');
				}
				else
				{
					response.headersSent?"":response.setHeader("Content-Type",'text/html; charset=utf-8');
				}
				if(response.writable)
				{
					if(typeof data == 'string' || Buffer.isBuffer(data))
					{
						if($Config.response)request.$responseData=`[-数据响应-]`+data
						return response.end(data);
					}
					else
					{
						if($Config.response)request.$responseData=`[响应数据${request.method}]`+request.pathname+'------数据响应为空'
						return response.end('');
					}
				}
				else
				{
					return false;
				}
			}
			response.json=function(data,tag)
			{
				if(response.writable)
				{
					if(data.$unique===undefined && request.data && request.data.$unique) data.$unique=request.data.$unique;
					if(tag || data instanceof Object)
					{
						return response.sender(JSON.stringify(data),true);
					}
					else
					{
						return response.sender(data);
					}
				}
				else
				{
					return false;
				}
			}

			request.location=function(url,code=302)
			{
				response.writeHead
				(
					code,
					{
						'Location': url
					}
				)
				response.end()
			}

			request.control=async function(url,met='default')
			{
				let res=$Sys.control(url);
				if(res)
				{
					let nm=new res();
					try 
					{
						return await nm[met](request,response);
					} 
					catch (error) 
					{
						console.error('[调用控制器失败]',error)
						return false;
					}
				}
				return false;
			}

			request.getCookie=function(k)
			{
				return $Sys.model('/http/cookie','getCookie')(request,k)
			}

			request.setCookie=function({key,value,time=0,path='/'})
			{
				return $Sys.model('/http/cookie','setCookie')(request,key,value,time,path)
			}

			request.pushCookie=function()
			{
				return $Sys.model('/http/cookie','sendCookie')(request,response)
			}

			if($Config.sessionAble)
			{
				let sessionCookie=request.getCookie($Config.session)
				if(!sessionCookie)
				{
					let token=$Sys.model('/fun/com','sha1',[$Sys.uid()+$Config.pass])
					request.sessionCookie=token
					$Sys.model('/http/cookie','setCookie')(request,$Config.session,token)
					$Sys.model('/http/cookie','sendCookie')(request,response)
				} 
				else
				{ 
					request.sessionCookie=sessionCookie
				}
			
				let _sysm=$Sys.model('/http/session')
				request.session=new _sysm(request)
			}


			var _____len=_path.indexOf($Config.type);
			if(_____len>0)
			{
				_path=_path.substring(0,_____len);
			}
			try 
			{
				for (let val of $Config.middle['http']) 
				{
					if(val[0] instanceof RegExp)
					{
						if(val[0].test(_path))
						{
							let result=await init_h.next(val[1],request,response);
							if(result)return true;
						}
					}
					else 
					{
						
						if(_path.indexOf(val[0])==0)
						{
							let result=await init_h.next(val[1],request,response);
							if(result)return true;
						}	
					}
				}
			} 
			catch (error) 
			{
				response.json($Sys.errIo(error,$Code.sys.middle))
				return true
			}

			request.data=request.post?request.post:request.query
			if(request.data.$unique)
			{
				request.user= $Sys.model('/socket/user');
			}
			
			var _all=_path.split('-');
			request.argument=_all.slice(1);
			var _alla=_all[0].split('/');
			var _allf=_alla.pop();
			var _allp=_alla.join("/");
			try 
			{
				var tomethod=$Sys.control(_allp);
				request.requestPath=_allp	
			} 
			catch (e) 
			{
				response.json($Sys.errIo(e,$Code.sys.control))
				return
			}

			try 
			{
				if(tomethod)
				{
					let nm=new tomethod(request,response);						
					await init_h.run(nm,_allf,request,response,_allp);
				}
				else
				{
					if(tomethod=$Sys.control((_all[0]==='/'?'':_all[0])+'/index'))
					{
						let nm=new tomethod(request,response);
						await init_h.run(nm,'tolerate',request,response,_allp);
					}
					else 
					{
						await init_h.run
						(
							{
								"fun":async ()=>
								{
									response.json(filters.echo($Code.sys.notFound))
								}
							},'fun',request,response,_allp
						);
					}
				}				
			} 
			catch (error) 
			{
				console.error('[执行错误]发生错误------'+`描述：`,error);
			}
		}

		static to(data,response)
		{
			if(data instanceof Object)
			{
				response.json(data,true);
			}
			else
			{
				response.sender(String(data));
			}
		}

		static async next (fun,request,response)
		{
			let data=await fun(request,response);
			if(data)
			{
				if(data!='_file')
				{
					if(data!==true)init_h.to(data,response);
				}
				return true;
			}
			else
			{
				return false;
			}
		}

		static async run(__con,ur,request,response,_allp)
		{	
			if(__con[ur])
			{
				request.requestMethod=ur
				try 
				{
					let data=await __con[ur](request,response);
					if(__con.$doc)
					{
						__con.$doc.requestPath=_allp
						if($Config.debug)request[Symbol.for('doc')]=__con.$doc
						
						if(__con.$doc.base.requestMethod!=request.method.toLowerCase())
						{
							response.json(filters.echo($Code.sys.requestMethod));
							return
						}

						
						let dataParm=await filters.eval(request[__con.$doc.base.requestMethod],__con.$doc.requestParam);
						if(__con.$doc.fun)
						{
							//dataParm={table:{},key:{},db:{},group:{},order:{},...dataParm}
							let data=await __con.$doc.fun(dataParm)
							if(data!==undefined)
							{
								init_h.to(data,response);
								return
							}
						}
						if(__con.$doc.service instanceof Object)
						{
							if(__con.$doc.service.path && __con.$doc.service.method)
							{
								dataParm.descript=`${__con.$doc.base.group}-${__con.$doc.base.descript?__con.$doc.base.descript:'暂无描述'}`
								dataParm.db=__con.$doc.service.db
								data=await $Sys.service(__con.$doc.service.path,__con.$doc.service.method,dataParm)
							}
							else
							{
								console.warn("[注意]doc未定义路径或方法");
								data=filters.echo($Code.sys.service)
							}
						}
						if(__con.$doc.funAfter)
						{
							let da=await __con.$doc.funAfter(data)
							if(da!==undefined)
							{
								init_h.to(da,response);
								return
							}                                            
						}
						if(__con.$doc.view)
						{
							data=(data!=undefined)?data:dataParm
							if(__con.$doc.view.worker)
							{
								data=await $Sys.viewWorker(__con.$doc.view.path,data,__con.$doc.view.cache)
							}
							else
							{
								data=await $Sys.view(__con.$doc.view.path,data,__con.$doc.view.cache)
							}
						}
						else
						{
							data=filters.echo({check:data})
						}
						
					}
					if(data!==undefined)init_h.to(data,response);	
					
				} 
				catch (e) 
				{
					if(e.cache)
					{
						response.sender(e.cache)
						return
					}
					if(e.string)
					{
						response.sender(e.string)
						return
					}
					response.json($Sys.errIo(e,$Code.sys.control))
				}	
			}
			else
			{
				
				response.json(filters.echo($Code.sys.notFound))
				console.warn("[注意]","未找到------"+ur+"方法");
			}					
		}

		static view()
		{

		}
        
    }
/*-------------------------------------------------------------------------------------------*/   
   
module.exports=init_h;