/*
NAME: 
DESCRIPTION: ;
PARAMETER:
    [
        {
            name : 'path',
			title : '资料路径',
            type : 'LineEdit',
            property : {tool_tip : '资料路径'},
        },
		{
            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("==============================>input原稿");

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);
}
if (!$.hasOwnProperty('auto_save')){
	PAR.auto_save = "no"
}
// drill tool manage
var drill_toll_manage = {}
try {

    var par = PAR;
    var config = {
        format: {
            "Gerber274x_1": {
                "nf1": 5,
                "nf2": 5,
                "units": "inch",
                "zeroes": "leading",
                "decimal": "no",
                "nf_comp": 0,
                "break_sr": "yes",
                "data_type": "ascii",
                "separator": "*",
                "threshold": 200,
                "drill_only": "no",
                "multiplier": 1,
                "resolution": 3,
                "tool_units": "inch",
                "coordinates": "absolute",
                "merge_by_rule": "no",
                "signed_coords": "no",
                "text_line_width": 0.0024
			},
            "Excellon2_1": {
                "nf1": 2,
                "nf2": 3,
                "units": "inch",
                "zeroes": "none",
                "decimal": "no",
                "nf_comp": 0,
                "break_sr": "yes",
                "data_type": "ascii",
                "separator": "nl",
                "threshold": 200,
                "drill_only": "no",
                "multiplier": 1,
                "resolution": 3,
                "tool_units": "inch",
                "coordinates": "absolute",
                "merge_by_rule": "no",
                "signed_coords": "no",
                "text_line_width": 0.0024
			}
        },
        odb: [{
            vaild: function(item){
                return /\.tgz$/ig.test(item.name) // 以.tgz结尾的
            }
        }],
        gerber: [
            {
                vaild: function(item){
                    return /\.art$/ig.test(item.name) // 以.art结尾的
                },
                type: "Gerber274x",
                format: "Gerber274x_1"
            },
            {
                vaild: function(item){
                    return /\.drl$/ig.test(item.name) // 以.drl结尾的
                },
                type: "Excellon2",
                format: "Excellon2_1"
            }
        ]
	}
    if(!par.hasOwnProperty("path")){throw "缺少资料路径"}
	if(_.isEmpty(Job)){throw "参数Job不存在"}
	var job = Job.toLowerCase()
	// 检查genesis中料号情况,存在则报警退出
	if(GEN.isJobExists({job:job})){throw "料号已经:"+job+"已经存在"}
	if(par.path[par.path.length-1]!=="/"){par.path = par.path + "/"}
	var path = par.path + Job
	// 检查待读入文件路径,路径不存在则报警退出
	if(!fs.exists(path)){throw "路径:"+path+"不存在"}

	// 检查文件格式,odb++或者gerber274,其中gerber存在一种特殊格式,其钻孔文件需要解析文件信息并更改文件内容才能读入(见特殊钻孔文件说明)
	var inputInfo = getJobInfo({path:path, job:job,config:config})
    if(inputInfo.type == "none"){throw "file error"}
    // 读入gerber或者odb++ 判断读入方式
    // 读入odb++
    if(/odb/ig.test(inputInfo.type)){
        importJob({db:"genesis",path:inputInfo.data.path,name:job})   
    }
    // 读入gerber
    if(/gerber/ig.test(inputInfo.type)){
        // ? 处理特殊钻孔文件
        inputInfo.data.forEach(function(file){
            if(/\.drl$/ig.test(file.name)){
                var backUpName = file.name+".backup"
                // 备份
                if(!fs.fileExists(file.dir+"/"+backUpName)){
                    fs.copyFile(file.path,file.dir+"/"+backUpName)
                }
                // 读取
                var data = fs.readFile(file.path)
                data = data.split("\n")
                var head = getHead(data)
                var body = data
                // 解析head
                var headData = head.filter(function(v){
                    return /Holesize.+Tolerance.+PLATED/ig.test(v)
                })
               
                headData.map(function(v){
                    var res = {
                        holesize: {},
                        tolerance: {},
                        attr: "",
                        unit: "",
                        quantity: 0
                    }
                    var holesize_tmp = /(Holesize.+)Tolerance/.exec(v)[1];
                    holesize_tmp =  holesize_tmp.split("=")
                    res.holesize.key = holesize_tmp[0].trim()
                    res.holesize.value = holesize_tmp[1].trim()
                    var Tolerance_tmp = /(Tolerance.{23})/.exec(v)[1];
                    Tolerance_tmp = Tolerance_tmp.split("=")[1].split("/")
                    res.tolerance.top = Tolerance_tmp[0].trim()
                    res.tolerance.bot = Tolerance_tmp[1].trim()
        
                    res.attr = /NON_PLATED/ig.test(v) ? "non_plated" : "plated"
                    res.unit = /MILS/ig.test(v) ? "inch" : "mm"
                    res.quantity = parseInt(v.split("=").pop())
                    if(!drill_toll_manage.hasOwnProperty(file.name)){
						drill_toll_manage[file.name] = {}
					}
                    drill_toll_manage[file.name][/(\d+)/ig.exec(res.holesize.key)[1]] = res
                })
                // 给body添加刀
                var count = 0
                body = body.filter(function(v){
					return !(/T\d+/ig.test(v))
				})
                body.forEach(function(v, i){
                    if(/^%$|^M00/ig.test(v)){
                        var k = "T" + getK(++count)
                        body[i] = v + "\n" + k 
                    }
                })
                // 写入文件
                var resStr = head.join("\n") + "\n" + body.join("\n")
                fs.writeFile(file.path,resStr)
            }
        })
        importGerber({job:job,step:"orig",db:"genesis",data:inputInfo.data})  
		var stepList = GEN.getStepList({job:job})
		var matrix = GEN.getMatrix({job:job})
		var drill_layers = Object.keys(matrix).filter(function(v){return matrix[v].layer_type=="drill"})
		stepList.forEach(function(step){
			GEN.openStep({job:job,name:step})     
			drill_layers.forEach(function(layer){
				var drill_tool_manage_info = drill_toll_manage[layer]
				var drill_tool_keys = Object.keys(drill_tool_manage_info).sort(function(a,b){return a-b})
				GEN.COM("tools_tab_reset")
				drill_tool_keys.forEach(function(key){
					var val = drill_tool_manage_info[key]
					GEN.COM("tools_tab_add", {
						num: key,
						type: /plated/ig.test(val.attr) ? "plate" : "nplate",
						min_tol: Number(val.tolerance.top),
						max_tol: Number(val.tolerance.bot),
						finish_size: Number(val.holesize.value),
						drill_size: Number(val.holesize.value)
					})
				})
				GEN.COM("tools_set",{layer:layer,thickness:0,user_params:1,slots:"by_length"})
			})
			GEN.closeStep()
		})  
    }

    // 保存 
	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 getJobInfo(props){
    var path = props.path
    var config = props.config
    var job = props.job
    var files = fs.listDir(path)
    files = files.filter(function(v){return v.isFile})   // 过滤出文件
    // 先判断是不是odb
    var odbFiles = files.filter(function(file){   // 拿到odb文件
        return config.odb.reduce(function(a,b){
            if(b.vaild(file)){
                a = true
            }    
            return a
        }, false)
    })
    if(odbFiles.length){
        return {
            type: "odb",
            data: odbFiles[0]
        }
    }
    var gerberFiles = files.filter(function(file){   // 拿到odb文件
        return config.gerber.reduce(function(a,b){
            if(b.vaild(file)){
                file.gerber = config.format[b.format];
                file.type = b.type;
                a = true
            }      
            return a
        }, false)
    })
    if(gerberFiles.length){
        return {
            type: "gerber",
            data: gerberFiles
        }
    }
    return "none"
}


function importJob(props){
    GEN.importJob(props);
}

function importGerber(props){  // job   db  step
    var job = props.job
    var step = props.step
    var files = props.data


    GEN.createJob({name:job,db:props.db})
    GEN.createStep({job:job,name:props.step})
    var gerberInfo = files.map(function(item){
        var gerberCfg = JSON.parse(JSON.stringify(item.gerber));
        gerberCfg.layer = item.name.toLowerCase()
        gerberCfg.path = item.path
        gerberCfg.format = item.type
        gerberCfg.job = job
        gerberCfg.step = step
        return gerberCfg
    })
    GEN.COM("input_manual_reset")
    gerberInfo.forEach(function(v){
        GEN.COM("input_manual_set",v)
    })
    GEN.COM("input_manual")
}

function getHead(arr,head){
	head = head || [];
	if(arr[0] != "%"){
		head.push(arr.shift())
		return getHead(arr,head)
	} else {
		return head
	}
}
function getK(count){
	return count < 10 ? "0" + String(count) : String(count)
}