/*
NAME: 
DESCRIPTION: ;
PARAMETER:
    [
        {
            name : 'step',
			title : 'Step',
            type : 'LineEdit',
            property : {tool_tip : 'orig'},
        },
        {
            name : 'rename_rule',
			title : '改名规则',
			type : 'TextEdit',
            property : {tool_tip : '支持正则匹配'},
            setter:function(obj,value,self){
                obj.setPlainText(value);
            },
            getter:function(obj,self){
                return obj.plainText
            }
        },
        {
            name : 'sort_rule',
			title : '排序规则',
			type : 'TextEdit',
            property : {tool_tip : '支持正则匹配'},
            setter:function(obj,value,self){
                obj.setPlainText(value);
            },
            getter:function(obj,self){
                return obj.plainText
            }
        },
		{
            name : 'auto_save',
			title : '自动保存',
            type : 'RadioBox',
            property : {
				item_list:[
					{name:'yes',text:'YES'},
					{name:'no',text:'NO'},
				],
				tool_tip:'是否自动保存料号开关'
			}
        }
	]
	
 VERSION_HISTORY:
	V1.00 2020-04-20 Scott Sun
	    1.新版本
		
 HELP:
 	<html><body bgcolor="#DDECFE">
		<font size="3" color="#003DB2"><p>功能简介</p></font>
		<p> input原稿 </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("==============================>rename and sort");

var $ = require('topcam.scriptfunc').argv();
var fs = require('fs');
var _ = require('lodash');
var database = require("topsin.database");
database.addConnection($.conf.database_conf, "DFM");
var QDfm = database.query("DFM");
if ($.conf.product_type == "aimdfm") {
    QDfm.updateRow({
        table: "pdm_aimdfm_task",
        data: {
            current_process_title: $.process_title
        },
        where: {
            id: $.task_id
        }
    });
}
var GEN = $.gen;
var fs = require("fs");
var Job = $.job_name;
var db = $.db
var Status = 'ok';
var resultData = [];
var PAR = {};
if ($.hasOwnProperty('script_parameter')) {
    PAR = JSON.parse($.script_parameter);
}
try {
    var par = PAR;
    if(par.step == ""){par.step = "orig"}
    var rename_rule, sort_rule;
    try {
        rename_rule = eval(par.rename_rule)
        sort_rule = eval(par.sort_rule)
    } catch (error) {
        throw "改名排序规则出错"
    }
    if (_.isEmpty(Job)) { throw "参数Job不存在" }
    var job = Job.toLowerCase()
    // 检查料号是否存在
	if(!GEN.isJobExists({job:job})){throw "料号已经:"+job+"不存在"}
	// 检查料号是否被打开
	if(!GEN.isJobOpen({job:job})){ GEN.openJob({job:job}) }
	// 检查料号是否能够check out
	if(GEN.checkInout({job:job,mode:"test"}) != 0){ throw "the job check" }
	GEN.checkInout({job:job,mode:"out"});
    var orig_step = par.step.toLowerCase()
    var stepList = GEN.getStepList({job:job})
    if(stepList.indexOf(orig_step) < 0){throw "step:"+orig_step+"不存在"}

    // 脚本开始
    var matrix = GEN.getMatrix({job:job})
    // 添加标准名
	var tl_name_matrix = tlNameMatrix({matrix:matrix,tl_name:rename_rule})   // 给matrix信息添加tl_name

    // 排序和设属性
	var ret = sortLayer({job:job, rule:sort_rule, matrix:tl_name_matrix})
	if(ret.err){throw err}
	var after_sort_matrix = ret.sortNames


    // 设置钻孔
    err = setDrill({job:job, matrix:after_sort_matrix})
    if(err){throw err}

    // 改名
    err = reName({job:job, matrix:after_sort_matrix, cfg:sort_rule})
    if(err){throw err}




    // 保存 
    if (/yes/ig.test(par.auto_save)) {
        GEN.checkInout({job: job,mode: "out"}) // 结束保存料号 关闭料号
        GEN.saveJob({ job: job });
        GEN.checkInout({job: job,mode: "in"})
        GEN.closeJob({ job: job })
    } else {
        GEN.checkInout({job: job,mode: "in" })
    }

    QDfm.updateRow({
        table: "pdm_aimdfm_task",
        data: {
            progress: 33.33
        },
        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
        };
    }
} catch (e) {
    Status = 'error';
    resultData.push({
        type: "error",
        title: "脚本执行出错!",
        detail: [{
            desc: _.toString(e)
        }]
    });
    return {
        status: Status,
        result_data: resultData
    };
}

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){
                var tmp = {
					orig_name: name2,
                    tl_name: item.tl_name,
                    sort: item.sort,
                }
                if(item.pg){
                    tmp.pg = 1
                }
				tlname_rules.push(tmp)
			})
		}
    })
    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){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})}
        }
        tlRule = tlRule.sort(function(a,b){return a.sort - b.sort})
		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)
            }
            if(tlRule[0].pg){
                return _.assign(val,{tl_name:tl_name,pg:true})
            }else{
                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 == ""){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;
                    if(value.pg){_item.pg = true}
                    sortNames.push(_item);
                }
            }
        });
        return flag;
	}).map(function(v){return v.name})
    miscName.forEach(function(n){ 
        if(matrix[n].context == 'board'){
            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(v.pg){
                GEN.matrixLayerAttr(_.assign({job:job,layer:v.name},{"context":"board","type":"power_ground", "polarity":"negative"}));
            } else {
                GEN.matrixLayerAttr(_.assign({job:job,layer:v.name},v.attr));
            }
        })
	}
	return {
		sortNames:sortNames
	}
}

function setDrill(props){   // 设置钻孔
    var job = props.job
	var matrix = props.matrix
	
    // 获取所有的钻孔层
    var drillLayer = matrix.filter(function(v){
        return (v.attr.type == "drill" ||v.attr.type == "rout") && v.attr.context == "board"
    })
    // 获取所有single层
    var signalLayer = matrix.filter(function(v){
        return (v.attr.type == "signal" || v.attr.type == "power_ground") && v.attr.context == "board"
    })
    
	var layerCount = signalLayer.length
    // findSignal 根据传入的数字找到对应的signal层 如 1 => top ; 2 => layer_2 
    function findSignal(num){
        return signalLayer[Number(num-1)].name
	}
    function doDrill(drills){  // 分析钻孔层
        return drills.map(function(v){
            if(v.tl_name == "drill" || v.tl_name=="rout" || v.tl_name=="outline" || v.tl_name=="drl" || v.tl_name=="gko"){
                return {start:findSignal(1), end:findSignal(layerCount), layer:v.name}
            } else {
                var tmp = /(\d+)-(\d+)/ig.exec(v.tl_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){return v.name != v.new_name})
	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}
			var replaceArr = tmp.slice(1)
			new_name = item.new_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)
			})
			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){
        if(v.orig_name !== 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})
}