/*
NAME: 
DESCRIPTION: ;
PARAMETER:
    [
        {
			name : 'config_path',
			title : '配置地址',
			type : 'LineEdit',
			property : {tool_tip : '配置的路径'},
		}
	]
	
 VERSION_HISTORY:
	V1.01 2020-04-17 Scott Sun
	    1.新版本
		
 HELP:
 	<html><body bgcolor="#DDECFE">
		<font size="3" color="#003DB2"><p>功能简介</p></font>
		<p> 数据标准化 </p>
		<br>
		<font size="3" color="#003DB2"><p>参数配置</p></font>
		<p> 客户配置 </p>
		<br>
		<font size="3" color="#003DB2"><p>注意事项</p></font>
		<p> 无 </p>
		<br>
	</body></html>	
*/
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// 引入模块 包
console.log("==============================================>data_format")
var $ = require('topcam.scriptfunc').argv();
var fs = require('fs');
var _ = require('lodash');
var mode = $.ikm ? "topcam" : "aimdfm";
var mail = require('topsin.mail');
var IKM = $.ikm; 
if (IKM==undefined ) { IKM = require('topcam.ikm6')($) }
var GEN = $.gen;
var GUI = $.gui || {};
var Job = $.job || $.job_name;
var JobId = $.job_id;
var db = $.db || IKM.db
var PAR = {}
if ($.par) {
	PAR = $.par
} else if ($.hasOwnProperty('script_parameter')){
	PAR = JSON.parse($.script_parameter);
}

if (mode === "aimdfm") {
	var database = require("topsin.database");
	database.addConnection($.conf.database_conf, "DFM");
	var QDfm = database.query("DFM");
	$.QDfm = QDfm;
	if ($.conf.product_type == "aimdfm") {
		QDfm.updateRow({
			table: "pdm_aimdfm_task",
			data: {
				current_process_title: $.process_title
			},
			where: { id: $.task_id }
		});
	}
}
var Status = 'ok';
var resultData = [];

// 邮件发送 获取客户信息
var db_customer = db.query("",function(q){
	return q.selectValue({
		table:'pdm_job',
		field:'customer_code',
		where:{id : JobId}
	})
});
var mailUserList = db.query("",function(q){
	return q.selectArrayMap({
		table:'sys_commu_grp_detail AS DETAIL LEFT JOIN sys_commu_grp AS GRP ON GRP.id = DETAIL.commu_grp_id',
		field:['DETAIL.mode, DETAIL.name, DETAIL.address'],
		where:{"GRP.sys_name":"quotation_fee"},
		order: "DETAIL.mode ASC"
	})
});
var mailUserTo=[], mailUserCc=[], mailUserBcc = [];
if(mailUserList && mailUserList.length) {
	mailUserList.map(function(item){
		if(item.mode == "mail_cc" && item.address){
			mailUserCc.push(item.address)
		} else if (item.mode == "mail_to" && item.address ) {
			mailUserTo.push(item.address)
		}else if (item.mode == "mail_bcc" && item.address ) {
			mailUserBcc.push(item.address)
		}
	})
}
var cam_workflow_info = IKM.get_jobinfo({jobid:JobId, jobinfo:"cam_workflow_info"});
try {
	if(cam_workflow_info && cam_workflow_info != ""){  
		throw cam_workflow_info
	}
	script_info({ msg: "Data formatting" ,result_severity:"info"})
	global._ERRORMAG = "Failed to data format";
	script_info({ progress: 35 })
    var par = PAR;
	if(!par.hasOwnProperty("config_path") || par.config_path==""){
		console.log("=========== ===cfg");
		par.config_path = "cam/input_data"
	};
	var db_customer = db.query("",function(q){
		return q.selectValue({
			table:'pdm_job',
			field:'customer_code',
			where:{id : JobId}
		})
	});
	if(_.isEmpty(db_customer)){throw "customer error"}
	if(db_customer && !(/^done$/ig.test(db_customer)) && db_customer != "" ){
		par.customer = db_customer
	}
    par.customer = par.customer[0].toUpperCase()+par.customer.slice(1).toLowerCase()
	var cfg = db.query("",function(q){
		return q.selectValue({
			table:'pub_conf',
			field:'text_data',
			where:{path : par.config_path}
		})
	});
	if (!cfg || cfg == ""){throw "cfg can not find"}
	var config = eval(cfg)
	var job = Job;
    if(_.isEmpty(job)) throw "没有传入料号名!";
    job = job.toLowerCase();
    
	var custCfg = config.customer[par.customer];	// 获取客户配置
	if(!custCfg){throw "config error"}
	// 料号验证
    if(!GEN.isJobExists({job:job})){
		script_info({ msg: "Find PN in system" ,result_severity:"error"})
		global._ERRORMAG = "No PN was found in system";
		throw "job "+ job+ " is not exist" }
    if(!GEN.isJobOpen({job:job})){GEN.openJob({job:job})}
	if(GEN.checkInout({job:job,mode:"test"}) != 0 && mode == "aimdfm"){
		script_info({ msg: "PN  Checkin" ,result_severity:"error"})
		global._ERRORMAG = "PN is not checkin";
		throw "the job check" }
	console.log("Checkout====== ========================>")
	GEN.checkInout({job:job,mode:"out"});
	console.log("Checkout   success==============================>")
	var profileRule = []
	if(custCfg.hasOwnProperty("mergerule")){ 
		var mergeRule = custCfg.mergerule
		if(mergeRule.drill){
			if (mergeRule.drill_second){
				var matrix = GEN.getMatrix({job:job})
				var layers = Object.keys(matrix)
				var is_second = false
				layers.forEach(function(layer){
					mergeRule.drill.forEach(function(item){
						var reg = new RegExp(item.orig_rule,"ig")
						if(reg.test(layer)){is_second = true}
					})
				})
				if(!is_second){
					mergeRule.drill = mergeRule.drill_second
				}
			}
			if(/string/ig.test(typeof(mergeRule.drill[0]))){  // drill层 计算
				var drill_layers = [];
				var tmp_layers = [];
				var matrix = GEN.getMatrix({job:job})
				// 计算最大值
				var layers = Object.keys(matrix)
				var maxnum = []
				layers.forEach(function(v){
					var hasrule
					mergeRule.drill.forEach(function(rule){
						var reg = new RegExp(rule,"ig")
						if(reg.test(v)){hasrule = rule}
					})
					if(hasrule){
						var reg = new RegExp(hasrule,"ig")
						var tmp = reg.exec(v)
						var num1 = Number(tmp[1])
						var num2 = Number(tmp[2])
						tmp_layers.push({num1:num1,num2:num2,layer:v})
						if(num1==1){
							drill_layers.push({num1:num1,num2:num2,layer:v})
						}
						maxnum.push(num1)
						maxnum.push(num2)
					}
				})
				var max = maxnum.sort(function(a,b){return b-a})[0]
				if (drill_layers.length > 0 && String(drill_layers[0].num2) == "NaN") {
					var maxLayer = tmp_layers.filter(function(v) {return v.num1 == max})
					GEN.COM("matrix_rename_layer",{job:job,matrix:"matrix",layer:maxLayer[0].layer,new_name:"drill"}) 
				}
				var drill_layer = drill_layers.filter(function(v){return v.num2 == max})
				if(drill_layer.length){
					drill_layer = drill_layer[0].layer
					GEN.COM("matrix_rename_layer",{job:job,matrix:"matrix",layer:drill_layer,new_name:"drill"}) 
				}
			}else if(/object/ig.test(typeof(mergeRule.drill[0]))){
				var matrix = GEN.getMatrix({job:job})
				// 计算最大值
				var layers = Object.keys(matrix)
				var tmp_step = GEN.getStepList({job:job})
				GEN.openStep({job:job,name:tmp_step[0]})
				layers.forEach(function(layer){
					var tmp = mergeRule.drill.filter(function(item){
						var reg = new RegExp(item.orig_rule,"ig")
						return reg.test(layer)
					})
					if(tmp.length){
						tmp = tmp[0]
						GEN.workLayer({name:layer,display_number:2,clear_before:'yes'})
						if(tmp.drill_type){
							GEN.COM("cur_atr_set,attribute=.drill,option="+tmp.drill_type)
							GEN.COM("sel_change_atr,mode=add")
						}
						GEN.selCopyOther({dest:'layer_name',target_layer:'drill',invert:'no',dx:0,dy:0,size:0})
						GEN.workLayer({name:"drill",display_number:2,clear_before:'yes'})
						GEN.COM("chklist_single,action=valor_dfm_nfpr,show=yes") 
						GEN.COM("chklist_cupd,chklist=valor_dfm_nfpr,nact=1,params=((pp_layer=.affected)(pp_delete=Duplicate)(pp_work=Features)(pp_drill=PTH\;NPTH\;Via\;PTH - Pressfit\;Via - Laser\;Via - Photo)(pp_non_drilled=Yes)(pp_in_selected=All)(pp_remove_mark=Remove)),mode=regular") 
						GEN.COM("chklist_run,chklist=valor_dfm_nfpr,nact=1,area=global") 
						GEN.deleteLayer({job:job,layer:["drill+++"]})
					}
				})
				GEN.closeStep()
			}
		}
		if(mergeRule.laser){
			var newdrills = mergeLaser({job:job, mergeRule:mergeRule.laser})
			var tmp_step = GEN.getStepList({job:job})
			GEN.openStep({job:job,name:tmp_step[0]})
			newdrills.forEach(function(v){
				GEN.workLayer({name:v,display_number:2,clear_before:'yes'})
				GEN.COM("chklist_single,action=valor_dfm_nfpr,show=yes")
				GEN.COM("chklist_cupd,chklist=valor_dfm_nfpr,nact=1,params=((pp_layer=.affected)(pp_delete=Duplicate)(pp_work=Features)(pp_drill=PTH\;NPTH\;Via\;PTH - Pressfit\;Via - Laser\;Via - Photo)(pp_non_drilled=Yes)(pp_in_selected=All)(pp_remove_mark=Remove)),mode=regular") 
				GEN.COM("chklist_run,chklist=valor_dfm_nfpr,nact=1,area=global")
				GEN.deleteLayer({job:job,layer:["drill+++"]})
			})
			GEN.deleteLayer({job:job,layer:newdrills.map(function(v){return v + "+++"})})
			GEN.closeStep()
		}
		if(mergeRule.profile){
			profileRule = mergeRule.profile
		}
	}
	// start    martix_tl_name
	console.log("get matrix ==== ======== job:" + job);
	var matrix = GEN.getMatrix({job:job}); 
	console.log("=========matrix:" + _.toString(matrix));
	console.log("matrix add tl_name :");
	var tl_name_matrix = tlNameMatrix({matrix:matrix,tl_name:custCfg.tl_name})   // 给matrix信息添加tl_name
	console.log("tl_name add end:");

	var format_cfg = config.data_format   // 拿到数据标准化配置
	// 排序和设属性
	script_info({ progress: 40 })
	var ret = sortLayer({job:job, rule:format_cfg, matrix:tl_name_matrix})
	if(ret.err){throw err}
	var after_sort_matrix = ret.sortNames
	
	// 改名
	script_info({ msg: "Change the name" ,result_severity:"info"})
	global._ERRORMAG = "Failed to change name"; 
	script_info({ progress: 50 })
	err = reName({job:job, matrix:after_sort_matrix, cfg:format_cfg})
	if(err){throw err}
	// 处理 yu cca   ftdrillx-x-np
	var tmp_step = GEN.getStepList({job:job})
	GEN.openStep({job:job,name:tmp_step[0]})
	var layers = Object.keys(GEN.getMatrix({job:job})) 
	layers.forEach(function(layer) {
		if(/^ftdrill(\d+)-(\d+)-np$/ig.test(layer)) {
		    var $1 = RegExp.$1;
			var $2 = RegExp.$2;
			// 1. 将此层改为npth属性
			// 2. 将此层合并到 ftdrill(\d+)-(\d+)l(如果有)
			GEN.workLayer({name:layer,display_number:2,clear_before:'yes'})
			GEN.COM("cur_atr_reset")
			GEN.COM("cur_atr_set,attribute=.drill,option=non_plated")
			GEN.COM("sel_change_atr,mode=add")
			GEN.COM("cur_atr_reset")
			var target = "ftdrill"+$1+"-"+$2+"l";
			if(GEN.isLayerExists({job:job, layer:target})) {
				GEN.copyLayer({source_job:job,source_step:tmp_step[0],source_layer:layer,dest_layer:target,mode:"append"})
				GEN.deleteLayer({job:job,layer:[layer]})
			} else {
				GEN.renameLayer({job:job,layer:layer,new_name:target})
			}
		}
	})
	GEN.closeStep()

	var tmp_matrix = GEN.getMatrix({job:job})

	// 钻孔名称再次更改
	var ftdrill_layer = Object.keys(tmp_matrix).filter(function(v){
		return tmp_matrix[v].layer_type=="drill" && tmp_matrix[v].context=="board"
	})
	var hasMainDrill = Boolean(ftdrill_layer.indexOf("ftdrill") >= 0)
	var layer_count = GEN.getLayerCount({job:job})
	ftdrill_layer.forEach(function(v){
		if(/(\d+)-(\d+)/.test(v)){
			var tmp = /(\d+)-(\d+)/.exec(v)
			var num1 = Number(tmp[1])
			var num2 = Number(tmp[2])
			var chabie = Math.abs(num2 - num1) 
			if(((num1 == 1 && num2 == layer_count) || num2 > layer_count) && !hasMainDrill){
				GEN.renameLayer({job:job,layer:v,new_name:"ftdrill"})
				if (ftdrill_layer[ftdrill_layer.length-1]!= v){
					GEN.matrixMoveRow({ job:job,layer:"ftdrill",after:ftdrill_layer[ftdrill_layer.length-1] }) 
				}
				hasMainDrill = !hasMainDrill
			} else if(chabie>1 && chabie < layer_count - 1){
				// 改名
				if(num1 > num2){
					var tmpv = "ftdrill"+num2+"-"+num1+"l";
					GEN.renameLayer({job:job,layer:v,new_name:tmpv.substr(0,v.length-1)})
				} else{ 
					GEN.renameLayer({job:job,layer:v,new_name:v.substr(0,v.length-1)})
				}
			} 
		}
	})
	// 设置钻孔
	err = setDrill({job:job})
	if(err){throw err}


	console.log("_______format _end_________wait_for_save:");

	if(/1352/ig.test(PAR.customer) ){
		// 钻孔拆分
		var tmp_step = GEN.getStepList({job:job})[0]
		GEN.openStep({job:job, name:tmp_step})
			GEN.units({type:"mm"})
			if(GEN.isLayerExists({job:job, layer:"ftdrill"})){
				var tmp_matrix_0 = GEN.getMatrix({job:job})
				var drill_layers = Object.keys(tmp_matrix_0).filter(function(v){return tmp_matrix_0[v].layer_type=="drill" && tmp_matrix_0[v].context == "board" && /^ftdrill/.test(v) && v !=="ftdrill"})
				GEN.workLayer({name:'ftdrill',display_number:2,clear_before:'yes'})
				GEN.selectByFilter({attribute:[{attribute:".drill",option:"plated"}]})
				if(GEN.getSelectCount() > 0) {
					GEN.selMoveOther({target_layer:'ftdrill_pth',invert:'no',dx:0,dy:0,size:0})
				}
				if(GEN.isLayerExists({job:job, layer:"ftdrill_pth"})) {
					GEN.workLayer({name:'ftdrill_pth',display_number:2,clear_before:'yes'})
					var syms = GEN.getLayerSymsHist({job:job,step:tmp_step,layer:'ftdrill_pth',units:'mm'})
					var tms = []
					for (var symbol in syms) {
						if (/^r\d/.test(symbol)) {
							if (parseFloat(symbol.slice(1)) <= 127){
								tms.push(symbol)
							}
						}
					}
					drill_layers.forEach(function(v) {
						GEN.selectByFilter({include_syms:tms.join(";")})
						if(GEN.getSelectCount() > 0){
							GEN.selCopyOther({dest:'layer_name',target_layer:v,invert:'no',dx:0,dy:0,size:0})
						}
					})
					GEN.selectByFilter({include_syms:tms.join(";")})

					if(GEN.getSelectCount() > 0) { GEN.selDelete()}
					GEN.selAllFeat()
					if(GEN.getSelectCount() > 0) {
						GEN.selMoveOther({target_layer:'ftdrill',invert:'no',dx:0,dy:0,size:0})
					}
					GEN.deleteLayer({job:job, layer:["ftdrill_pth"]})
				}
			}
		GEN.closeStep()
	}

	var job_attrs = db.query("",function(q){
		return q.selectValue({
			table:'pdm_job',
			field_format:{job_attrs:'json'},
			field:'job_attrs',
			where:{id : JobId}
		})
	});
	if (!job_attrs ) { job_attrs = {}}

	GEN.checkInout({job:job,mode:"out"})  // 结束保存料号 关闭料号
	GEN.saveJob({ job: job });
	GEN.checkInout({job:job,mode:"in"})
	GEN.closeJob({job:job});
	GEN.COM("open_job,job="+job);	
	
	script_info({ msg: "Creating Profile" ,result_severity:"info"})
	global._ERRORMAG = "Failed to create profile"; 

	script_info({ progress: 55 })
	var all_layer = Object.keys(tmp_matrix);
	// 没有outline层
		// 判断有没有profile
		var tmp_step = GEN.getStepList({job:job})[0]
		GEN.openStep({job:job, name:tmp_step})
		if(!hasProfle({job:job, step:tmp_step})){  // 如果没有profile
			if(/^2171$/ig.test(par.customer)){
				// 看看有没有 outline 层或者rout层
				var outlines = all_layer.filter(function(layer){return /^rout$/.test(layer)})
				if(all_layer.indexOf("outline") >= 0){outlines.unshift("outline")}
				if(outlines.length){
					outlines.forEach(function(layer){
						if(!hasProfle({job:job, step:tmp_step})) {
							GEN.selClearFeature()
							GEN.workLayer({name:layer,display_number:2,clear_before:'yes'})
							GEN.selAllFeat()
							if(GEN.getSelectCount() > 0) { GEN.COM("sel_create_profile,create_profile_with_holes=no") }
						}
					})
				}
			} else if (/^yucca$/ig.test(par.customer)) {
				if(all_layer.indexOf("outline") >= 0) {
					GEN.workLayer({name:"outline",display_number:2,clear_before:'yes'})
					GEN.selAllFeat()
					if(GEN.getSelectCount() > 0) {
						// GEN.COM("sel_create_profile,create_profile_with_holes=no");
						// if(!hasProfle({job:job, step:tmp_step})){
						createOutline({job:job, step:tmp_step,  profileRule:["^outline$"]});
						// }
					}
					else { createOutline({job:job, step:tmp_step,  profileRule:profileRule}) }
				} else {
					createOutline({job:job, step:tmp_step,  profileRule:profileRule})
				}
			} else if (/^wistron$/ig.test(par.customer)) {
				var contours = all_layer.filter(function(layer){return /contour/.test(layer)})
				// 判读有没有outline层 全选outline层创建
				if(all_layer.indexOf("outline") >= 0){
					GEN.workLayer({name:"outline",display_number:2,clear_before:'yes'})
					GEN.selAllFeat()
					if(GEN.getSelectCount() > 0) {
						// GEN.COM("sel_create_profile,create_profile_with_holes=no");
						// if(!hasProfle({job:job, step:tmp_step})){
						createOutline({job:job, step:tmp_step,  profileRule:["^outline$"]})
						// }
					}
					else { createOutline({job:job, step:tmp_step,  profileRule:profileRule}) }
				} else if (contours.length) {  
					// 过滤上下方的框
					profileRule.unshift("contour");
					createOutline({job:job, step:tmp_step,  profileRule:profileRule})
				} else {
					createOutline({job:job, step:tmp_step,  profileRule:profileRule})
				}
			} else if (/^vivo$/ig.test(par.customer)) {
				// 判断有没有line层
				if(all_layer.indexOf("line") >= 0){
					GEN.workLayer({name:"line",display_number:2,clear_before:'yes'})
					GEN.selAllFeat()
					if(GEN.getSelectCount() > 0) { GEN.COM("sel_create_profile,create_profile_with_holes=no") }
				} else if(all_layer.indexOf("array") >= 0) {
					GEN.workLayer({name:"array",display_number:2,clear_before:'yes'})
					GEN.selAllFeat()
					if(GEN.getSelectCount() > 0) {
						// GEN.COM("sel_create_profile,create_profile_with_holes=no");
						// if(!hasProfle({job:job, step:tmp_step})){
							createOutline({job:job, step:tmp_step,  profileRule:["^array$"]})
						// }
					}
					else { createOutline({job:job, step:tmp_step,  profileRule:profileRule}) }
				}else if(all_layer.indexOf("top") >= 0) {
					GEN.selClearFeature()
					GEN.workLayer({name:"top",display_number:2,clear_before:'yes'})
					// 判断是否有外框
					// 将top层根据形状创建一个 并将top层的线跟弧拷贝到辅助层tmp1
					GEN.COM("profile_limits,layers=top,type=lyrfilter,margin=0")
					GEN.selectByFilter({feat_types:"line\;arc\;surface"})
					if(GEN.getSelectCount() > 0) {
						GEN.selCopyOther({dest:'layer_name',target_layer:"tmp1",invert:'no',dx:0,dy:0,size:0})
						// 根据形状画出线在辅助层 tmp2
						GEN.COM("profile_to_rout,layer=tmp2,width=1")
						// 看tmp1是否有跟tmp2碰到 没碰到就创建失败 有碰到的则递归选择线 然后创建
						GEN.workLayer({name:"tmp1",display_number:2,clear_before:'yes'})
						GEN.selRefFeat({layers:"tmp2",use:"filter",mode:"touch"})
						if(GEN.getSelectCount() > 0 ){
							(function(){
								GEN.selMoveOther({target_layer:'tmp3',invert:'no',dx:0,dy:0,size:0})
								GEN.selRefFeat({layers:"tmp3",use:"filter",mode:"touch"})
								if(GEN.getSelectCount() > 0) {
									arguments.callee()
								}
							})()
							if(GEN.isLayerExists({job:job, layer:"tmp3"})){
								GEN.workLayer({name:"tmp3",display_number:2,clear_before:'yes'})
								GEN.selAllFeat()
								GEN.COM("sel_create_profile,create_profile_with_holes=no")
							}
						}
					}
					if(GEN.isLayerExists({job:job, layer:"tmp1"})){GEN.deleteLayer({job:job, layer:["tmp1"]})}
					if(GEN.isLayerExists({job:job, layer:"tmp2"})){GEN.deleteLayer({job:job, layer:["tmp2"]})}
					if(GEN.isLayerExists({job:job, layer:"tmp3"})){GEN.deleteLayer({job:job, layer:["tmp3"]})}
				}
			} else if (/^1352$/ig.test(par.customer)) {
				if(all_layer.indexOf("outline") >= 0) {
					GEN.workLayer({name:'outline',display_number:2,clear_before:'yes'})
					GEN.selAllFeat()
					if(GEN.getSelectCount() > 0) {
						if(GEN.GEN_TYPE == "genesis"){
							GEN.selCreateProfile()
						} else {
							// GEN.COM("sel_create_profile,create_profile_with_holes=no")
							// if(!hasProfle({job:job, step:tmp_step})){
								createOutline({job:job, step:tmp_step,  profileRule:["^outline$"]})
							// }
						}
					}
				} 
				if(!hasProfle({job:job, step:tmp_step})){
					createOutline({job:job, step:tmp_step,  profileRule:profileRule})
				}
			}

			// if(profileRule[0] == "outline" && /1352/ig.test(PAR.customer)) {
			// 	GEN.workLayer({name:'outline',display_number:2,clear_before:'yes'})
			// 	GEN.selAllFeat()
			// 	if(GEN.getSelectCount() > 0) {
			// 		if(GEN.GEN_TYPE == "genesis"){
			// 			GEN.selCreateProfile()
			// 			// GEN.COM("sel_create_profile,create_profile_with_holes=no")
			// 		} else {
			// 			GEN.COM("profile_limits,layers=outline,type=lyrfilter,margin=0")
			// 		}
			// 	}
			// 	var hasProfile = GEN.getProfile({job:job, step:tmp_step})
			// 	GEN.closeStep()
			// 	if(hasProfile.match(/\n/ig).length == 1){
			// 		createOutline({job:job, step:tmp_step,  profileRule:profileRule})
			// 	}
			// } else {
			// 	createOutline({job:job, step:tmp_step,  profileRule:profileRule})
			// }
			var hasProfile = GEN.getProfile({job:job, step:tmp_step})
			if(hasProfile.match(/\n/ig).length == 1){
				script_info({ msg: "Failed to create profile" ,result_severity:"warn"})
				global._ERRORMAG = "Failed to create profile"; 

				job_attrs.readin_result = "Failed to create profile"
				db.query("",function(q){
					return q.updateRow({
						table:'pdm_job',
						data:{job_attrs:job_attrs},
						update_policy:{attr_data:'json_merge'},
						where:{id : JobId}
					})
				});
				throw "创建profile失败,请手动创建好profile后仅执行分析步骤"
			}
		} 


	script_info({ msg: "Data format is done" ,result_severity:"warn"})
	global._ERRORMAG = false; 

	db.query("",function(q){
		return q.updateRow({
			table:'pdm_job',
			data:{job_attrs:job_attrs},
			update_policy:{attr_data:'json_merge'},
			where:{id : JobId}
		})
	});

    // end
    GEN.checkInout({job:job,mode:"out"})  // 结束 保存料号 关闭料号
	GEN.saveJob({ job: job });
	GEN.checkInout({job:job,mode:"in"})
	GEN.closeJob({job:job})
    
	if (mode === "aimdfm") {
		$.QDfm.updateRow({
			table: "pdm_aimdfm_task",
			data: {
				progress: 60
			},
			where: { id: $.task_id }
		});
		if (GEN.hasError()) {
			Status = 'error';
			resultData.push({ type: "error", title: "GEN错误!", detail: [{ desc: _.join(GEN.STATUS, "\n") }] });
			return {
				status: Status,
				result_data: resultData
			};
		} else {
			resultData.push({ type: "info", title: "操作完成, 请注意检查!" });
			return {
				status: Status,
				result_data: resultData
			};
		}
	}else {
		return "Done"
	}		
}
catch (e) {
	script_info({ result_severity: "error" })
	IKM.msg(_.join(GEN.STATUS, "\n"))
	IKM.msg(e)
	if(global._ERRORMAG){
		script_info({ msg: global._ERRORMAG });
		var job_attrs = db.query("",function(q){
			return q.selectValue({
				table:'pdm_job',
				field_format:{job_attrs:'json'},
				field:'job_attrs',
				where:{id : JobId}
			})
		});
		if (!job_attrs ) { job_attrs = {}}
		job_attrs.readin_result = global._ERRORMAG
		db.query("",function(q){
			return q.updateRow({
				table:'pdm_job',
				data:{job_attrs:job_attrs},
				update_policy:{attr_data:'json_merge'},
				where:{id : JobId}
			})
		});
	}
	IKM.crud("deleteRow", {
		table: "pdm_job_jobattr",
		where:{job_id:JobId, attr_name:"cam_workflow_info"},
	})
	IKM.save_job_info({jobid:JobId, jobinfohash:{cam_workflow_info:"err"}});
	global._STATUS = "err";
	checkIn()
	// 发送邮件
	// sendEmail({
	// 	subject:db_customer + ' / '+Job+ " format error",
	// 	content:_.toString(e)
	// })
    Status = 'error';
    resultData.push({type: "error", title: "脚本执行出错!", detail: [{desc: _.toString(e)}]});
	return (mode === "aimdfm") ? {status: Status, result_data: resultData} : "Error";
}

function checkIn(){
	GEN.COM("open_job,job="+Job+",open_win=no,disk_map=,job_map=")
	GEN.AUX("set_group,group=99")
	GEN.COM("close_job,job="+Job+"")
	GEN.COM("disp_on")
	GEN.COM("origin_on")
	GEN.COM("disp_on")
	GEN.COM("origin_on")
	GEN.COM("checkin_closed_job,job="+Job);
}

function tlNameMatrix(props){  // 设置标准名
	var matrix = props.matrix
	var tlname_rules = []
	props.tl_name.forEach(function(item){
		if(typeof item.orig_name == "string"){
			tlname_rules.push(item)
		} else {
			item.orig_name.forEach(function(name2){
				tlname_rules.push({
					orig_name: name2,
					tl_name: item.tl_name
				})
			})
		}
	})
	var res = Object.keys(matrix).map(function(key){  // 将matrix信息添加tl_name 如果没有tl_name 就返回原信息
		var val = matrix[key]
		if(val.hasOwnProperty("tl_name")){delete val.tl_name}
		var tlRule = tlname_rules.filter(function(rule){
			if(rule.orig_name === key){return true}
			var reg = new RegExp(rule.orig_name,"ig")
			return reg.test(key)
		})
		if(tlRule.length == 0){
			if(/^comp_\+_/.test(key)){   
				return _.assign(val,{tl_name:key})
			}
			return val
		}
		for(var i=0;i<tlRule.length;i++){
			if(tlRule[i].orig_name === key){return _.assign(val,{tl_name:tlRule[0].tl_name})}
		}
		var reg = new RegExp(tlRule[0].orig_name,"ig")
		var tmp = reg.exec(key)
		if(tmp && tmp.length){
			var replaceArr = tmp.slice(1)
			var tl_name = tlRule[0].tl_name
			var params = {}
			for(var i = 0; i<replaceArr.length;i++){
				params["$"+(i+1)] = replaceArr[i]
			}
			replaceArr.forEach(function(v,i){
				tl_name = tl_name.replace("($"+(i+1)+")",v)
			})
			tl_name = replaceTlName(tl_name)
			function replaceTlName(name){
				var tmp = /(\([^)]*\))/ig.exec(name)
				if(!tmp){ return name }
				var param_arr = tmp[1].match(/\$\d+/ig)
				var newname = tmp[1]
				param_arr.forEach(function(v){
					newname = newname.replace(new RegExp("\\"+v,"ig"), params[v])
				})
				newname = name.replace(tmp[1],eval(newname))
				return replaceTlName(newname)
			}
			return _.assign(val,{tl_name:tl_name})
		}else {
			return _.assign(val,{tl_name:tlRule[0].tl_name})
		}
	})
	return res
}

function sortLayer(props){  // 排序方法  {job:要排序的料号, rule: {要改名的规则}
    var job = props.job
	var matrix =  GEN.getMatrix({job:job})
	var tl_matrix = props.matrix
	var matrixName = Object.keys(matrix).sort(function(a,b){return matrix[a].row - matrix[b].row})
    var matrixFirst = matrixName[0];  // 记录matrix中第一位
	var sortNames = [];
    var miscName = tl_matrix.filter(function (value) { // 找出需要排序的名称列表
		var flag = true;
		if ((!value.tl_name || value.tl_name == "") && !/^comp_\+_/.test(value.name)) {
			return true
		}
		var tl_name = value.tl_name
		props.rule.forEach(function (item, i) {
			var evalReg = "/" + item.tl_name + "/ig.test(tl_name)";
			if (tl_name == item.tl_name || eval(evalReg)) {
				flag = false;
				if (tl_name === item.tl_name) {
					var _item = JSON.parse(JSON.stringify(item));
					_item.value = i;
					_item.name = value.name
					_item.rule = item.tl_name
					sortNames.push(_item);
				} else {
					var _item = JSON.parse(JSON.stringify(item));
					_item.value = i;
					var str = "/" + item.tl_name + "/ig.exec(tl_name)"
					_item.value2 = eval(str).pop() - 0;
					_item.name = value.name
					_item.rule = item.tl_name
					_item.tl_name = tl_name;
					sortNames.push(_item);
				}
			}
		});
		return flag;
	}).map(function (v) {
		return v.name
	})
    miscName.forEach(function(n){ 
        if(matrix[n].context == 'board' && !/^comp_\+_/.test(matrix[n].name)){
            GEN.matrixLayerAttr({job:job,layer:n,context:'misc'}) 
        }
    })
    sortNames = sortNames.sort(function(a,b){
        return a.value - b.value || a.value2 - b.value2
	})
	// 排序
    if(sortNames.length){
        if(sortNames[0].name !== matrixFirst) {  // 如果第一位和matrix中第一位不同,先把第一位插入到最前面
            GEN.matrixMoveRow({ job:job,layer:sortNames[0].name,before:matrixFirst })
        }
        sortNames.forEach(function(v,i,arr){
            if(i !== 0){
                GEN.matrixMoveRow({ job:job,layer:v.name,after:arr[i-1].name })            
			} 
			if(!/^comp_\+_/.test(v.name)){
				GEN.matrixLayerAttr(_.assign({job:job,layer:v.name},v.attr));
			}
        })
	}
	return {
		sortNames:sortNames
	}
}

function setDrill(props){   // 设置钻孔
    var job = props.job
	var matrix = _.values(GEN.getMatrix({job:job}))
	
    // 获取所有的钻孔层
    var drillLayer =matrix.filter(function(v){
        return (v.layer_type == "drill" || v.layer_type == "rout") && v.context == "board"
    })
    // 获取所有single层
    var signalLayer =matrix.filter(function(v){
        return v.layer_type == "signal" && v.context == "board"
	})
	console.log("=================>setdrill:drillLayer:" + _.toString(drillLayer));
	console.log("=================>setdrill:signalLayer:" + _.toString(signalLayer));
	
	var layerCount = GEN.getLayerCount({job:job})
    // findSignal 根据传入的数字找到对应的signal层 如 1 => top ; 2 => layer_2 
    function findSignal(num){
		console.log(num)
		var tmpnum = Number(num-1)
		if(tmpnum > signalLayer.length -1){
			tmpnum = signalLayer.length -1
		}
        return signalLayer[tmpnum].name
	}
    function doDrill(drills){  // 分析钻孔层
        return drills.map(function(v){
            if(v.name == "ftdrill" || v.name=="rout" || v.name=="outline"){
                return {start:findSignal(1), end:findSignal(layerCount), layer:v.name}
            } else {
                var tmp = /(\d+)-(\d+)/ig.exec(v.name);
                if(tmp){
                    var start = findSignal(tmp[1]); 
                    var end = findSignal(tmp[2]); 
                    return {start:start, end:end, layer:v.name}
                } else {
                    return 0;
                }
            }
        })
    }
	var drillSetList = doDrill(drillLayer);   // 分析得到钻孔设置结果
	drillSetList = drillSetList.filter(function(v){return v!==0})
    drillSetList.forEach(function(v){
        GEN.matrixLayerDrill({job:job,layer:v.layer,start:v.start ,end:v.end})
    })
}

function reName(props) { // 改名 par{job:要改名的料号, rule: {要改名的规则}
    var job = props.job
	var matrix = props.matrix
	var cfg = props.cfg

	matrix = matrix.filter(function(v){
		if(v.name == v.new_name){
			IKM.save_layerinfo({ jobid: JobId, layer: v.name, layerinfohash: { layer_name_final: v.new_name }})
		}
		return v.name != v.new_name
	})
	var tmp = [];
	matrix = matrix.filter(function(v){
		// 在数据库层信息里找v.name 找得到就直接改名
		var new_name = IKM.get_layerinfo({jobid: JobId, layer: v.name, layerinfo: "layer_name_final" })
		var layers_tmp = Object.keys(GEN.getMatrix({job:job}));
		if(new_name && new_name!="" && new_name != v.name && layers_tmp.indexOf(new_name) < 0){
			IKM.save_layerinfo({ jobid: JobId, layer: v.name, layerinfohash: { layer_name_final: new_name }})
			tmp.push(v.name + " ---- " +new_name)
			GEN.renameLayer({job:job,layer:v.name,new_name:new_name})
			return false
		} else {
			return true
		}
	})

	if(matrix.length > 0){
		var rename_list = matrix.map(function(item){
			var new_name;
			var tl_name = item.tl_name
			var rule = item.rule
			if(rule === tl_name){
				new_name = item.new_name
			} else {
				var reg = new RegExp(rule,"ig")
				var tmp = reg.exec(tl_name)
				if(!tmp){return undefined}
				 // ["1","10","np"]
				var replaceArr = tmp.slice(1)
				new_name = item.new_name
				var params = {}
				for(var i = 0; i<replaceArr.length;i++){
					if(/\d+/ig.test(replaceArr[i])) {
						params["$"+(i+1)] = replaceArr[i]
					} else {
						params["$"+(i+1)] = "'" + replaceArr[i] + "'"
					}
				}
				replaceArr.forEach(function(v,i){
					tl_name = tl_name.replace("($"+(i+1)+")",v)
				})
				// {"tl_name":"d1-10-np","new_name":"ftdrill($1)-($2)-($3)"}
				new_name = replaceTlName(new_name)
				function replaceTlName(name){
					var tmp = /(\([^)]*\))/ig.exec(name)
					if(!tmp){ return name }
					var param_arr = tmp[1].match(/\$\d+/ig)
					var newname = tmp[1]
					param_arr.forEach(function(v){
						newname = newname.replace(new RegExp("\\"+v,"ig"), params[v])
					})
					newname = name.replace(tmp[1],eval(newname))
					return replaceTlName(newname)
				}
			}
			return {
				orig_name: item.name,
				new_name: new_name
			}
		})
		rename_list = rename_list.filter(function(v){
			var flag = true
			if(!v){flag = false}
			if(!v.orig_name || !v.new_name ){flag = false}
			return flag
		})
		rename_list.forEach(function(v){
			var layers_tmp = Object.keys(GEN.getMatrix({job:job}));
			if(v.orig_name !== v.new_name && layers_tmp.indexOf(v.new_name) < 0){
				IKM.save_layerinfo({ jobid: JobId, layer: v.orig_name, layerinfohash: { layer_name_final: v.new_name }})
				GEN.renameLayer({job:job,layer:v.orig_name,new_name:v.new_name})
			}
		});
	}
	
	// 最后 如果第一个 最后一个不是top bottom  就手动修改
	var afterMatrix = GEN.getMatrix({job:job});
	var signals = Object.keys(afterMatrix).filter(function(v){return afterMatrix[v].layer_type=="signal" && afterMatrix[v].context=="board"})
	signals = signals.sort(function(a,b){return afterMatrix[a].row - afterMatrix[b].row})
	var topSignal = signals[0]
	var botSignal = signals[signals.length -1]
	if(topSignal !== "top"){
		if(!GEN.isLayerExists({job:job, layer:"top"})){
			IKM.save_layerinfo({ jobid: JobId, layer: topSignal, layerinfohash: { layer_name_final: "top" }})
			GEN.renameLayer({job:job,layer:topSignal,new_name:"top"})
		}
	}
	if(botSignal !== "bottom"){
		if(!GEN.isLayerExists({job:job, layer:"bottom"})){
			IKM.save_layerinfo({ jobid: JobId, layer: botSignal, layerinfohash: { layer_name_final: "bottom" }})
			GEN.renameLayer({job:job,layer:botSignal,new_name:"bottom"})
		}
	}
}

function mergeLaser(props){ // 合并钻孔
	var tmp = []
	if(!props.mergeRule){return}
	var mergeRuleRegs = props.mergeRule.regs
	var mergeTlname = props.mergeRule.tl_name
	var newdrills = []
	var merge_info = {}
	var regs = mergeRuleRegs
    var job = props.job;
    var step = GEN.getStepList({job:job})[0];
    var maxDrill = {name:"",value:0};
    function getDrl(str, r){
		var reg = new RegExp(r,"ig")
        var num = reg.exec(str);  // 匹配出 num-num
        var tmp = [];
        for(var i = Number(num[1]);i<num[2];i++){
            if(i == 1){
                maxDrill = Number(num[2]) >  maxDrill.value? {name:str,value:Number(num[2])} : maxDrill;
			}
			var layername = mergeTlname.replace("($1)", i)
			layername = layername.replace("($2)", i+1)
            tmp.push(layername);
        }
        return tmp;
    } 
    var matrix = GEN.getMatrix({job:job});
    GEN.openStep({job : job,name:step});
    for(var key in matrix){
		var val = matrix[key];
		var tmpregs = regs.filter(function(v){
			var reg = new RegExp(v,"ig")
			return reg.test(val.name)
		})
        if(tmpregs.length > 0){
			var reg = tmpregs[0]
			var mergeTo = getDrl(val.name, reg) // 要合并到的地方
			merge_info[val.name] = mergeTo
			mergeTo.forEach(function(layerName){
                if(GEN.isLayerExists({job : job ,layer:layerName.toLowerCase()}) && newdrills.indexOf(layerName.toLowerCase()) < 0){
                    GEN.deleteLayer({job:job, layer:layerName.toLowerCase()})
                }
                if(!GEN.isLayerExists({job : job ,layer:layerName.toLowerCase()})){
                    GEN.createLayer({job:job,layer:layerName.toLowerCase(),conext:'board',type:val.layer_type});
                    newdrills.push(layerName.toLowerCase())
                }
                GEN.workLayer({name:layerName.toLowerCase(),display_number:1,clear_before:'yes'});
				GEN.copyLayer({source_job:job ,mode:'append',source_step:step,source_layer:val.name,dest_layer:layerName.toLowerCase()});
				if(/drl|drill/ig.test(val.name) && tmp.indexOf(val.name) < 0) {
					tmp.push(val.name)
				}
            })
        }
	}
	GEN.affectedLayer({affected:"no",mode:"all"});
	GEN.clearLayers();
	tmp.forEach(function(layer) {
		GEN.COM("matrix_rename_layer,job="+job+",matrix=matrix,layer="+layer+",new_name="+layer.replace(/drl|drill/, "merage"))
	})
	GEN.closeStep();
	return newdrills
}

function createOutline(props){
	var profileRule = props.profileRule
	console.log("----profileRule------->:" + _.toString(profileRule));
    var job = props.job
    var step = props.step
    var matrix = GEN.getMatrix({job:job})
	var outlines = Object.keys(matrix).filter(function(v){
		var flag = false
		profileRule.forEach(function(rule){
			var reg = new RegExp(rule,"ig")
			if(reg.test(v)){
				flag = true
			}
		})
		return flag
	})
    // fs.writeFile("/home/toplinker/samba/scott_test/tmp", _.toString(outlines))
	var drill_layer = Object.keys(matrix).filter(function(v){return matrix[v].layer_type=="drill" && matrix[v].context == "board"})
	var tmp = "drill_all";
	if(GEN.isLayerExists({job:job, layer:tmp})) { GEN.deleteLayer({job:job, layer:[tmp]})}
	GEN.createLayer({job:job,layer:'drill_all'});
	drill_layer.forEach(function(d_layer) {
		GEN.workLayer({name:d_layer,display_number:2,clear_before:'yes'})
		GEN.selCopyOther({dest:'layer_name',target_layer:tmp,invert:'no',dx:0,dy:0,size:0})
	})
	
	GEN.closeStep()

	if (outlines.indexOf("outline") >= 0) {
		outlines = outlines.reduce(function(a,b){
			if(b != "outline") {
				a.push(b)
			}
			return a
		}, ["outline"])
	}
    var tmp_outline;
    if(outlines.length){
        if( outlines.length){
			for(var i =0;i<outlines.length;i++){
				tmp_outline = outlines[i]
				if(cl(tmp_outline)) {
					return true
				}else{
					continue
				}
			}
        } else {
            return cl(outlines[0])
        }
    }else{return false}
    function cl(l){
		GEN.openStep({job:job, name:step})
        GEN.affectedLayer({affected:'no',mode:'all'})
		GEN.workLayer({name:l,display_number:2,clear_before:"yes"})
		var bk = l + "_bk"
		var bk2 = l + "_bk2"
		selCopyLayer({job:job,layer:bk})
		selCopyLayer({job:job,layer:bk2})
		GEN.workLayer({name:bk,display_number:2,clear_before:"yes"})
		l = bk
		GEN.selectByFilter({feat_types:"line\;arc"})
		GEN.selReverse()
		if(GEN.getSelectCount()>0){GEN.selDelete()}
        GEN.selClearFeature()
        GEN.COM("sel_cut_data,det_tol=1,con_tol=1,rad_tol=0.1,filter_overlaps=no,delete_doubles=no,use_order=yes,ignore_width=yes,ignore_holes=none,start_positive=yes,polarity_of_touching=same")
		if(/1352/ig.test(PAR.customer) ){
			GEN.COM("sel_polarity,polarity=positive")
		}
		GEN.selectByFilter({feat_types:"surface"})
		GEN.selReverse()
		if(GEN.getSelectCount()>0){GEN.selDelete()}
		GEN.selContourize()
		if(!/1352/ig.test(PAR.customer) ){
			GEN.selectByFilter({feat_types:"surface"})
			GEN.selReverse()
			if(GEN.getSelectCount()>0){GEN.selDelete()}
		}
		var tmp_layer = l+"+++"
        GEN.selRefFeat({layers:tmp,use:'filter',mode:'touch'})
        if(GEN.getSelectCount() > 0){
            var tmp_outline2 = l + "_tmp"
			selCopyLayer({job:job,layer:tmp_outline2})
			if(/1352/ig.test(PAR.customer) ){
				// 1. worklayer bk2 删除非线 递归touch tmp_outline2
				GEN.workLayer({name:bk2,display_number:2,clear_before:"yes"})
				GEN.selectByFilter({feat_types:"pad;surface;text"})
				if(GEN.getSelectCount() > 0) {GEN.selDelete()}
				touch(tmp_outline2)
				// 2. worklayer tmp_outline2 cuttingdata selContourize
				GEN.workLayer({name:tmp_outline2,display_number:2,clear_before:"yes"})
				GEN.COM("sel_cut_data,det_tol=1,con_tol=1,rad_tol=0.1,filter_overlaps=no,delete_doubles=no,use_order=yes,ignore_width=yes,ignore_holes=none,start_positive=yes,polarity_of_touching=same")
				GEN.selContourize()
				GEN.deleteLayer({job:job, layer:bk2})
				GEN.deleteLayer({job:job, layer:tmp_outline2 + "+++"})
			}
			GEN.workLayer({name:l,display_number:2,clear_before:"yes"})
            GEN.selAllFeat()
            GEN.selDelete()
			GEN.workLayer({name:tmp_outline2,display_number:2,clear_before:"yes"})
			GEN.COM("sel_clean_holes,max_size=200,clean_mode=x_and_y")
			GEN.COM("sel_surf2outline,width=1")
            GEN.selAllFeat()
            selCopyLayer({job:job,layer:l})
			GEN.workLayer({name:l,display_number:2,clear_before:"yes"})
			GEN.selClearFeature()
			if(GEN.GEN_TYPE == "genesis"){
				GEN.selCreateProfile()
			} else {
				GEN.COM("profile_limits,layers="+l+",type=lyrfilter,margin=0")
			}
			GEN.selectByFilter({profile:"in"})
			if(GEN.getSelectCount()> 0){GEN.selDelete()}
            GEN.deleteLayer({job:job, layer:tmp_layer})
			GEN.deleteLayer({job:job, layer:tmp_outline2})
			if(GEN.isLayerExists({job:job,layer:"outline"})){GEN.deleteLayer({job:job,layer:"outline"})}
			GEN.renameLayer({job:job, layer:l,new_name:'outline'})
			GEN.deleteLayer({job:job, layer:l})
			if(GEN.isLayerExists({job:job, layer:bk2})){ GEN.deleteLayer({job:job, layer:bk2}) }
            return true
        }
		GEN.deleteLayer({job:job, layer:l})
		if(GEN.isLayerExists({job:job, layer:bk2})){ GEN.deleteLayer({job:job, layer:bk2}) }
		GEN.deleteLayer({job:job, layer:[tmp_layer]})
		GEN.deleteLayer({job:job, layer:[tmp_layer]})
        return false
	}
	if(GEN.isLayerExists({job:job, layer:tmp})){ GEN.deleteLayer({job:job, layer:[tmp]}) }

	
}
function exportInfo(info){
    fs.writeFile("/home/toplinker/samba/Test_Scott/tmp", _.toString(info))
}
function touch(layer) {
	GEN.selRefFeat({layers:layer,use:"filter",mode:"touch"})
	if(GEN.getSelectCount() > 0) {
		GEN.selMoveOther({target_layer:layer,invert:'no',dx:0,dy:0,size:0})
		touch(layer)
	}
}

function selCopyLayer(props){  // 拷贝选择的到辅助层
    var layer = props.layer
    var job = props.job
    if(GEN.isLayerExists({job:job,layer:layer})){
        GEN.deleteLayer({job:job,layer:layer})
    }
    GEN.selCopyOther({dest:'layer_name',target_layer:layer})
}

function script_info(props){  // result_severity  progress
	if (mode === "aimdfm") {
		$.QDfm.updateRow({
			table: "pdm_aimdfm_task",
			data: props,
			where: { id: $.task_id }
		});
	}
}

function sendEmail(msg) {
	if(mailUserList && mailUserList.length) {
		var info = {
			host:"10.90.79.37",
			port:"25",
			from:'topdfm@sys.com',
			connection_type:mail.ConnectionType.TCP,
			subject:msg.subject,
			content:msg.content
		};
		info.to = mailUserTo.join(";")
		info.cc = mailUserCc.join(";")
		info.bcc = mailUserBcc.join(";")
		var err = mail.sendMail(info);
		if (err.isValid()) {
			print(err.text());
		}
	}
}

function hasProfle(props) {
	var now_profile = GEN.getProfile({job:props.job, step:props.step})
	return now_profile && now_profile.match(/\n/ig) && now_profile.match(/\n/ig).length != 1
}