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


//严格模式
/*-------------------------------------------------------------------------------------------*/	
'use strict';
/*-------------------------------------------------------------------------------------------*/
const util = require('util');
const fs = require('fs');
const path=require('path')
const zlib=require('zlib');

// 文件访问操作
/*-------------------------------------------------------------------------------------------*/	
	class file
	{
		static async start(req,res)
		{
			const stat = util.promisify(fs.stat);	
			try 
			{
				const st=await stat($Config.root+req.pathname);
				if(st && st.isFile())
				{
					let ext=path.extname(req.pathname);
					if($Meta[ext])res.setHeader('Content-Type',$Meta[ext]);
					file.output(req.pathname, req, res,st);
				}
				else
				{
					file.notFind(res);
				}
			} 
			catch (error) 
			{
				file.notFind(res);
			}
			return '_file';
		}

		//是否在允许访问的域名里,因为可能直接访问首页html文件，所以加了个路径参数
		static ref(_referer,_path)
		{
			var _tagM;
			var _k;
			var _len=$Config.allowHost.length;
			if(_len>0 && _referer)
			{
				for(_k in $Config.allowHost)
				{
					if (_referer.indexOf($Config.allowHost[_k]) == 0)
					{
						_tagM = true;  
						break;
					}
				}
				return _tagM; 
			}
			else if(_len==0)
			{
				return true;
			}
			else if(_path.indexOf('.html')!=-1 || _path=='')
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		static meta(_path)
		{
			var ext=path.extname(_path);
			if($Config.zlibNo.includes(ext))return true
			else return false			
		}

		static notFind(response)
		{
			if(!response.headersSent)
			{
				response.removeHeader('Content-Encoding');
			}
			let pip=fs.createReadStream($Config.index404)
			pip.on('error',function(){
				response.end('<center><h2>404</h2></center>');
			});
			pip.pipe(response)
		}

		static output(_path1,request,response,stat)
    	{

    		if(!file.ref(request.headers['referer'],_path1))
    		{
    			response.end('');
    			return;
    		}
			_path1=$Config.root+_path1;
			
			function send()
			{
				let pip=fs.createReadStream(_path1);
				pip.on('error',function(){
					file.notFind(response);
				});

				let pip1=pip.pipe(zlib.createGzip())
				pip1.on('error',function(){
					file.notFind(response);
				});
				if($Config.zlibCache)
				{
					let write=fs.createWriteStream(_path1+'._zip_');
					write.on('error',function(){console.info('[文件]','创建压缩缓存失败')})
					write.on('close',function(){fs.utimes(_path1+'._zip_',new Date(),new Date(stat.mtime),()=>{})});
					pip1.pipe(write)
				}
				pip1.pipe(response);
			}
			
    		function zip(size)
    		{
    			if($Config.zlib==true && size>$Config.zlibMax && !file.meta(_path1))
				{	
					response.setHeader('Content-Encoding','gzip');
					if($Config.zlibCache)
					{
						fs.stat(_path1+'._zip_',function(err,stmtime){
							if(stmtime && (new Date(stat.mtime).getTime())==(new Date(stmtime.mtime).getTime()))
							{
								let pip=fs.createReadStream(_path1+'._zip_')
								pip.on('error',function(){
									send();	
								});
								pip.pipe(response)
							}
							else
							{
								send();	
							}	
						})
					}
					else
					{
						send();	
					}
				}
				else
				{
					let pip=fs.createReadStream(_path1)
					pip.on('error',function(){
						file.notFind(response);
					});
					pip.pipe(response);					
				}
    		}
 
			if($Config.cache)
			{
				if(request.headers['if-modified-since'])
				{
					var d1=new Date(request.headers['if-modified-since']).getTime();
					var d2=new Date(stat.mtime).getTime();
					if(d1===d2)
					{
						response.writeHead(304);
						response.end();
					}
					else
					{
						var date=new Date(stat.mtime);
						response.setHeader('Last-Modified',date.toUTCString());
						zip(stat.size);
					}
				}
				else
				{
					var date=new Date(stat.mtime);
					response.setHeader('Last-Modified',date.toUTCString());
					zip(stat.size);
				}
			}
			else
			{
				zip(stat.size);
			}		
    	}
  }
/*-------------------------------------------------------------------------------------------*/    
module.exports=file;