var fs=require("fs");
var objsettings=require("../config/objsettings");
var settings=require("../config/settings");
const crypto = require('crypto');
const md5 = require('md5');

class System {
	static declare(ns) {
		var ar = ns.split('.');
		var root = System;
		for (var i = 0, len = ar.length; i < len; ++i) {
			var n = ar[i];
			if (!root[n]) {
				root[n] = {};
				root = root[n];
			} else {
				root = root[n];
			}
		}
	}
	static register(key,ClassObj){
		if(System.objTable[key]!=null){
			throw new Error("相同key的对象已经存在");
		}else{
			let obj=new ClassObj();
			System.objTable[key]=obj;
		}

		return System.objTable[key];
	}
	static getResult3(data,req,okmsg="操作成功",errmsg="操作失败"){
		var total=data.total;
		data=data.hits;
		var sources=[];
		data.forEach(function(d){
			sources.push(d._source);
		})
		var result={
			status:0,
			msg:okmsg,
			total:total,
			data:sources,

		};
		if(req && req.session && req.session.bizmsg){
			result.bizmsg=req.session.bizmsg;
			req.session.bizmsg=null;
		}else{
			result.bizmsg="empty";
		}
		if(!data){
			result.status=-1;
			result.msg=errmsg;
		}
		return result;
	}
	static getResult4(j,req,okmsg="操作成功",errmsg="操作失败"){

		var aggs = j.aggregations;
		var codes_count = aggs.ncl_one_codes_count;
		var bucketlist = codes_count.buckets;
		var bucklist = [];
		bucketlist.forEach(function(d){
			bucklist.push(d);
		})
		var data = j.hits;
		var total=data.total;
		var hit=data.hits;
		var sources=[];
		hit.forEach(function(d){
			sources.push(d._source);
		})
		var result={
			status:0,
			msg:okmsg,
			total:total,
			data:sources,
			buckets:bucklist,
		};
		if(req && req.session && req.session.bizmsg){
			result.bizmsg=req.session.bizmsg;
			req.session.bizmsg=null;
		}else{
			result.bizmsg="empty";
		}
		if(!hit){
			result.status=-1;
			result.msg=errmsg;
		}
		return result;
	}
	static getResultjuhe4(j,req,okmsg="操作成功",errmsg="操作失败"){

		var aggs = j.aggregations;
		var codes_count = aggs.ncl_one_codes_count;
		var bucketlist = codes_count.buckets;
		var bucklist = [];
		bucketlist.forEach(function(d){
			bucklist.push(d);
		})
		var result={
			status:0,
			msg:okmsg,
			buckets:bucklist,
		};
		if(!bucklist){
			result.status=-1;
			result.msg=errmsg;
		}
		return result;
	}

	static getErrResult2(errmsg) {
		return this.getResult2(null, null, null, errmsg);
	}
	static getResult2(data,req,okmsg="操作成功",errmsg="操作失败"){
		var result={
			status:0,
			msg:okmsg,
			data:data,
		};
		if(req && req.session && req.session.bizmsg){
			result.bizmsg=req.session.bizmsg;
			req.session.bizmsg=null;
		}else{
			result.bizmsg="empty";
		}
		if(!data){
			result.status=-1;
			result.msg=errmsg;
		}
		return result;
	}
	static getResult(p,cbk,okmsg="success",errmsg="fail"){
		var result={
			status:0,
			msg:null,
			rtnData:null,
		};
		if(!p){
			result.status=-1;
			result.rtnData=null;
			result.msg=errmsg;
			return cbk(result);
		}else{
			p.then(function(r){
		     result.rtnData=r;
				 result.msg=okmsg;
				 return cbk(result);
			}).catch(function(err){
		     result.status=-1;
				 result.rtnData=null;
				 result.msg=errmsg;
				 return cbk(result);
			});
		}
	}
	static getObject(objpath){
		var packageName=objpath.split(".")[0];
		var filename=objpath.split(".")[1];
		var classpath=objsettings[packageName];
		var objabspath=classpath+"/"+filename+".js";
		if(System.objTable[objabspath]!=null){
			console.log("get cached obj");
			return System.objTable[objabspath];
		}else{
			console.log("no cached...");
			var ClassObj=require(objabspath);
			return System.register(objabspath,ClassObj);
		}
	}
  static getUiConfig(appid){
		var configPath=settings.basepath+"/app/base/db/metadata/"+appid+"/index.js";
		if(settings.env=="dev"){
			delete require.cache[configPath];
		}
		var configValue =require(configPath);
		return configValue;
	}
	static getUiConfig2(appid){
		var configPath=settings.basepath+"/app/base/db/metadata/index.js";
		// if(settings.env=="dev"){
		// 	console.log("delete "+configPath+"cache config");
		// 	delete require.cache[configPath];
		// }
		delete require.cache[configPath];
		var configValue =require(configPath);
		return configValue[appid];
	}
	static get_client_ip(req) {
    var ip = req.headers['x-forwarded-for'] ||
        req.ip ||
        req.connection.remoteAddress ||
        req.socket.remoteAddress ||
        (req.connection.socket && req.connection.socket.remoteAddress) || '';
		var x= ip.match(/(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$/);
    if(x){
			return x[0];
		}else {
			return "localhost";
		}

	};
	static trim(str) {
		return str ? str.trim() : "";
	}
	static y2f(y) {
		if(!y) {
			return 0;
		}
		return (Number(y) * 100).toFixed(0);
	}

	static f2y(f) {
		if(!f) {
			return 0;
		}
		return parseFloat((Number(f) / 100).toFixed(2));
	}

	static f2y4list(list, fields, prev) {
		if(!list || list.length == 0 || !fields || fields.length == 0) {
			return;
		}
		prev = prev || "";
		for(var item of list) {
			for(var f of fields) {
				var v = item[f];
				if(v) {
					try {
						item[f + "_y"] = prev + parseFloat((Number(v) / 100).toFixed(2));	
					} catch (error) {
						console.log(error);
					}
				}
			}
		}
	}

	static encryption(data) {
		if(!data) {
			return "";
		}
		let AES_conf = settings.apiconfig.AES;
		let key = AES_conf.key;
		let iv = AES_conf.iv;

		var cipherChunks = [];
		var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
		cipher.setAutoPadding(true);
		cipherChunks.push(cipher.update(data, 'utf8', 'base64'));
		cipherChunks.push(cipher.final('base64'));
		return cipherChunks.join('');
	}

	static decryption(data){
		if(!data) {
			return "";
		}
		let AES_conf = settings.apiconfig.AES;
		let key = AES_conf.key;
		let iv = AES_conf.iv;

		var cipherChunks = [];
		var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
		decipher.setAutoPadding(true);
		cipherChunks.push(decipher.update(data, 'base64', 'utf8'));
		cipherChunks.push(decipher.final('utf8'));
		return cipherChunks.join('');
	}

	static getSign(params, secret, exceptKeys = []) {
		console.log("---------签名参数-----------", params, secret, exceptKeys);
		let keys = Object.keys(params).sort();
		let signArr = [];
		for (let k = 0; k < keys.length; k++) {
			let tKey = keys[k];
			if (exceptKeys.indexOf(tKey) == -1 && params[tKey]) {
				signArr.push(tKey + "=" + params[tKey]);
			}
		}

		let signStr = signArr.join("&") + "&key=" + secret;
		let sign = md5(signStr).toUpperCase();

		console.log("---------签名结果-----------", signStr, sign);
		return sign;
	}
	// static buildObjectFactory(){
	// 	for(var k in objsettings){
	// 		let classpath=objsettings[k];
	// 		console.log(objsettings);
	// 		var p=new Promise(function(resolve,reject){
	// 			fs.readdir(classpath,function(err,rs){
	// 			 if(rs){
	// 				 rs.forEach(function(r){
	// 					 var fpath=classpath+"/"+r;
	// 					 var ClassObj=require(fpath);
	// 					 System.register(fpath,ClassObj);
	// 				 });
	// 				 resolve();
	// 			 }
	// 		 });
	// 		});
	// 		return p;
	// 	}
	// }
}
Date.prototype.Format = function(fmt)
{ //author: meizz
  var o = {
    "M+" : this.getMonth()+1,                 //月份
    "d+" : this.getDate(),                    //日
    "h+" : this.getHours(),                   //小时
    "m+" : this.getMinutes(),                 //分
    "s+" : this.getSeconds(),                 //秒
    "q+" : Math.floor((this.getMonth()+3)/3), //季度
    "S"  : this.getMilliseconds()             //毫秒
  };
  if(/(y+)/.test(fmt))
    fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
  for(var k in o)
    if(new RegExp("("+ k +")").test(fmt))
  fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
  return fmt;
}
System.objTable = {};
module.exports=System;

// rc=System.getObject("tool.restClient");
// rc.execDownload("http://gsb-public.oss-cn-beijing.aliyuncs.com/netsharp_SPEPdWCBp4xAtzrsiTcZWQ2CXK7aW8Dz.jpg","./a.jpg").then(function(result){
// 	console.log(result.stderr);
// });

  // var oss=System.getObject("tool.oss");

	// oss.upfile(key,"/usr/devws/OMC/igirl-api/r3resize.jpg").then(function(result){
	//   console.log(result);
	// }).then(function(){
	// 	oss.downfile(key).then(function(result){
	// 	  console.log(result);
	// 	});
	// });



	// eimage=System.getObject("tool.easyimage");
	// eimage.convert("/usr/devws/OMC/igirl-api/r3.jpg","/usr/devws/OMC/igirl-api/r4.pdf").then(function(r,t){
	// 	console.log(r)
	// 	console.log(t)
	// }).catch(function(e){
	// 	console.log(e);
	// });
	//var coss=System.getObject("service.convertoss");
//======================模板嵌套
// tmplTable=attrs=>`
// 	<table>
// 	${attrs.map(attr=>`
// 	    <tr><td>${attr.id}</td><td>${attr.name}</td></tr>
// 	`).join()}
// 	</table>
// `
// var data=[
// 	{id:1,name:'jy'},
// 	{id:2,name:'tom'},
// ]
// var rtnHtml=tmplTable(data)
// console.log(rtnHtml)

//========根据模板，动态生成javascript表达式，根据模板生成脚本表达式
// let template = `
// <ul>
//   <% for(let i=0; i < data.supplies.length; i++) { %>
//     <li><%= data.supplies[i] %></li>
//   <% } %>
// </ul>
// `;

// //===>通过郑则编译为
// echo('<ul>');
// for(let i=0; i < data.supplies.length; i++) {
//   echo('<li>');
//   echo(data.supplies[i]);
//   echo('</li>');
// };
// echo('</ul>');


// let evalExpr = /<%=(.+?)%>/g;
// let expr = /<%([\s\S]+?)%>/g;

// template = template
//   .replace(evalExpr, '`); \n  echo( $1 ); \n  echo(`')
//   .replace(expr, '`); \n $1 \n  echo(`');
// console.log(template)
// //生成脚本表达式
// template = 'echo(`' + template + '`);';

// //=========模板编译函数--返回渲染函数
// function compile(template){
// 	const evalExpr = /<%=(.+?)%>/g;
// 	const expr = /<%([\s\S]+?)%>/g;

// 	template = template
// 	  .replace(evalExpr, '`); \n  echo( $1 ); \n  echo(`')
// 	  .replace(expr, '`); \n $1 \n  echo(`');

// 	template = 'echo(`' + template + '`);';

// 	let script =
// 	`(function parse(data){
// 	  let output = "";

// 	  function echo(html){
// 		output += html;
// 	  }

// 	  ${ template }

// 	  return output;
// 	})`;

// 	return script;
//   }
