// checkrule
package admin

import (
	"fmt"
	"jy/extract"
	. "jy/mongodbutil"
	ju "jy/util"
	"log"
	qu "qfw/util"
	"qfw/util/elastic"
	"regexp"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
)

func init() {
	//正则规则验证
	Admin.POST("/check/prerule", func(c *gin.Context) {
		rule, _ := c.GetPostForm("s_rule")
		con, _ := c.GetPostForm("s_testcon")
		str := checkPreReg(con, rule)
		c.JSON(200, gin.H{"rep": str})
	})
	Admin.POST("/check/extrule", func(c *gin.Context) {
		rule, _ := c.GetPostForm("s_rule")
		con, _ := c.GetPostForm("s_testcon")
		field, _ := c.GetPostForm("s_field")
		tmp := checkCoreReg(field, con, rule)
		c.JSON(200, gin.H{"rep": tmp})
	})
	Admin.POST("/check/auditrule", func(c *gin.Context) {
		rule, _ := c.GetPostForm("s_rule")
		con, _ := c.GetPostForm("s_testcon")
		tmp := checkAuditReg(con, rule)
		c.JSON(200, gin.H{"rep": tmp})
	})
	Admin.POST("/check/backrule", func(c *gin.Context) {
		rule, _ := c.GetPostForm("s_rule")
		con, _ := c.GetPostForm("s_testcon")
		str := checkBackReg(con, rule)
		c.JSON(200, gin.H{"rep": str})
	})

	//lua脚本验证
	//通用前置验证
	Admin.GET("/check/lua/pre", func(c *gin.Context) {
		version := c.Query("version")
		s_code := c.Query("s_code")
		rule, _ := Mgo.FindOne("rule_pre", `{"s_code":"`+s_code+`"}`)
		(*rule)["_id"] = qu.BsonIdToSId((*rule)["_id"])
		c.HTML(200, "check_luapre.html", gin.H{"version": version, "code": s_code, "rule": &rule, "infos": getCheckInfos()})
	})
	Admin.POST("/check/lua/prerule", func(c *gin.Context) {
		luascript, _ := c.GetPostForm("s_luascript")
		infoid, _ := c.GetPostForm("infoid")
		code, _ := c.GetPostForm("s_code")
		name, _ := c.GetPostForm("s_name")
		extinfo := checkPreScript(code, name, infoid, luascript)
		c.JSON(200, gin.H{"rep": extinfo})
	})
	//通用后置验证
	Admin.GET("/check/lua/back", func(c *gin.Context) {
		version := c.Query("version")
		s_code := c.Query("s_code")
		rule, _ := Mgo.FindOne("rule_back", `{"s_code":"`+s_code+`"}`)
		(*rule)["_id"] = qu.BsonIdToSId((*rule)["_id"])
		c.HTML(200, "check_luaback.html", gin.H{"version": version, "code": s_code, "rule": &rule, "infos": getCheckInfos()})
	})
	Admin.POST("/check/lua/backrule", func(c *gin.Context) {
		luascript, _ := c.GetPostForm("s_luascript")
		infoid, _ := c.GetPostForm("infoid")
		version, _ := c.GetPostForm("s_version")
		code, _ := c.GetPostForm("s_code")
		name, _ := c.GetPostForm("s_name")
		extinfo := checkBackScript("rule_back", code, name, version, infoid, luascript, true)
		c.JSON(200, gin.H{"rep": extinfo})
	})
	//抽取前置验证
	Admin.GET("/check/lua/corepre", func(c *gin.Context) {
		vid := c.Query("vid")
		pid := c.Query("pid")
		sid := c.Query("sid")
		s_code := c.Query("s_code")
		rule, _ := Mgo.FindOne("rule_logicpre", `{"s_code":"`+s_code+`"}`)
		(*rule)["_id"] = qu.BsonIdToSId((*rule)["_id"])
		c.HTML(200,
			"check_luacorepre.html",
			gin.H{"code": s_code, "rule": &rule, "infos": getCheckInfos(),
				"pid": pid, "vid": vid, "sid": sid},
		)
	})
	Admin.POST("/check/lua/coreprerule", func(c *gin.Context) {
		luascript, _ := c.GetPostForm("s_luascript")
		infoid, _ := c.GetPostForm("infoid")
		code, _ := c.GetPostForm("s_code")
		name, _ := c.GetPostForm("s_name")
		extinfo := checkPreScript(code, name, infoid, luascript)
		c.JSON(200, gin.H{"rep": extinfo})
	})
	//抽取验证
	Admin.GET("/check/lua/core", func(c *gin.Context) {
		vid := c.Query("vid")
		pid := c.Query("pid")
		sid := c.Query("sid")
		s_code := c.Query("s_code")
		rule, _ := Mgo.FindOne("rule_logicore", `{"s_code":"`+s_code+`"}`)
		(*rule)["_id"] = qu.BsonIdToSId((*rule)["_id"])
		c.HTML(200,
			"check_luacore.html",
			gin.H{"code": s_code, "rule": &rule, "infos": getCheckInfos(),
				"pid": pid, "vid": vid, "sid": sid},
		)
	})
	Admin.POST("/check/lua/corerule", func(c *gin.Context) {
		luascript, _ := c.GetPostForm("s_luascript")
		infoid, _ := c.GetPostForm("infoid")
		code, _ := c.GetPostForm("s_code")
		name, _ := c.GetPostForm("s_name")
		extinfo := checkCoreScript(code, name, infoid, luascript)
		c.JSON(200, gin.H{"rep": extinfo})
	})
	//抽取后置验证
	Admin.GET("/check/lua/coreback", func(c *gin.Context) {
		vid := c.Query("vid")
		pid := c.Query("pid")
		sid := c.Query("sid")
		s_code := c.Query("s_code")
		rule, _ := Mgo.FindOne("rule_logicback", `{"s_code":"`+s_code+`"}`)
		(*rule)["_id"] = qu.BsonIdToSId((*rule)["_id"])
		c.HTML(200,
			"check_luacoreback.html",
			gin.H{"code": s_code, "rule": &rule, "infos": getCheckInfos(),
				"pid": pid, "vid": vid, "sid": sid},
		)
	})
	Admin.GET("/check/lua/pkgcoreback", func(c *gin.Context) {
		vid := c.Query("vid")
		pid := c.Query("pid")
		sid := c.Query("sid")
		s_code := c.Query("s_code")
		rule, _ := Mgo.FindOne("pkg_logicback", `{"s_code":"`+s_code+`"}`)
		(*rule)["_id"] = qu.BsonIdToSId((*rule)["_id"])
		c.HTML(200,
			"check_pkgluacoreback.html",
			gin.H{"code": s_code, "rule": &rule, "infos": getCheckInfos(),
				"pid": pid, "vid": vid, "sid": sid},
		)
	})
	Admin.POST("/check/lua/corebackrule", func(c *gin.Context) {
		luascript, _ := c.GetPostForm("s_luascript")
		infoid, _ := c.GetPostForm("infoid")
		code, _ := c.GetPostForm("s_code")
		name, _ := c.GetPostForm("s_name")
		vid, _ := c.GetPostForm("vid")
		version, _ := Mgo.FindById("version", vid, `{"version":1}`)
		extinfo := checkBackScript("rule_back", code, name, qu.ObjToString((*version)["version"]), infoid, luascript, true)
		c.JSON(200, gin.H{"rep": extinfo})
	})
	//清理逻辑脚本验证
	Admin.GET("/check/lua/clearlogic", func(c *gin.Context) {
		vid := c.Query("vid")
		pid := c.Query("pid")
		s_code := c.Query("s_code")
		rule, _ := Mgo.FindOne("clearulelogic", `{"s_code":"`+s_code+`"}`)
		(*rule)["_id"] = qu.BsonIdToSId((*rule)["_id"])
		c.HTML(200,
			"check_luaclearlogic.html",
			gin.H{"code": s_code, "rule": &rule, "infos": getCheckInfos(),
				"pid": pid, "vid": vid},
		)
	})
	Admin.POST("/check/lua/checkclearlua", func(c *gin.Context) {
		luascript, _ := c.GetPostForm("s_luascript")
		code, _ := c.GetPostForm("s_code")
		name, _ := c.GetPostForm("s_name")
		rid, _ := c.GetPostForm("rid")
		resultcoll, _ := c.GetPostForm("resultcoll")
		if rid == "" || resultcoll == "" {
			c.JSON(200, gin.H{"rep": nil})
		} else {
			extinfo := checkClearScript(code, name, resultcoll, rid, luascript)
			c.JSON(200, gin.H{"rep": extinfo})
		}

	})
}

//获取信息
func getCheckInfos() *[]map[string]interface{} {
	infos, _ := Mgo.Find("bidding", `{}`, `{"_id":-1}`, `{"title":1}`, false, 0, 100)
	for _, v := range *infos {
		v["_id"] = qu.BsonIdToSId(v["_id"])
	}
	return infos
}

//正则前置过滤检查
func checkPreReg(content, ruleText string) string {
	tmpstr := ""
	qu.Try(func() {
		tmp := strings.Split(ruleText, "__")
		var pattern string
		if strings.Contains(tmp[0], "\\u") {
			tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
			tmp[0] = strings.Replace(tmp[0], "\\\\u", "\\u", -1)
			pattern, _ = strconv.Unquote(`"` + tmp[0] + `"`)
		} else {
			pattern = tmp[0]
		}
		if len(tmp) == 2 {
			reg := regexp.MustCompile(pattern)
			tmpstr = reg.ReplaceAllString(content, tmp[1])
		} else {
			reg := regexp.MustCompile(pattern)
			tmpstr = reg.ReplaceAllString(content, "")
		}
	}, func(err interface{}) {
		tmpstr = fmt.Sprint(err)
	})
	return tmpstr
}

//正则后置过滤检查
func checkBackReg(content, ruleText string) string {
	tmpstr := ""
	qu.Try(func() {
		tmp := strings.Split(ruleText, "__")
		var pattern string
		if strings.Contains(tmp[0], "\\u") {
			tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
			tmp[0] = strings.Replace(tmp[0], "\\\\u", "\\u", -1)
			pattern, _ = strconv.Unquote(`"` + tmp[0] + `"`)
		} else {
			pattern = tmp[0]
		}
		if len(tmp) == 2 {
			reg := regexp.MustCompile(pattern)
			tmpstr = reg.ReplaceAllString(content, tmp[1])
		} else {
			reg := regexp.MustCompile(pattern)
			tmpstr = reg.ReplaceAllString(content, "")
		}
		log.Println(tmp[0])
	}, func(err interface{}) {
		tmpstr = fmt.Sprint(err)
	})
	return tmpstr
}

//正则抽取检查
func checkCoreReg(field, content, ruleText string) map[string]string {
	rep := map[string]string{}
	qu.Try(func() {
		//处理正负数修正
		ptmp := strings.Split(ruleText, "#")
		sign := 0
		if len(ptmp) == 2 {
			if ptmp[1] == "正" {
				sign = 1
			} else if ptmp[1] == "负" {
				sign = -1
			}
		}
		tmp := strings.Split(ptmp[0], "__")
		if len(tmp) == 2 {
			epos := strings.Split(tmp[1], ",")
			posm := map[string]int{}
			for _, v := range epos {
				ks := strings.Split(v, ":")
				if len(ks) == 2 { //(.*)招标公告(.*)__2:projectname,4:area
					posm[ks[1]] = qu.IntAll(ks[0])
				} else {
					posm[field] = qu.IntAll(ks[0])
				}
			}
			var pattern string
			if strings.Contains(tmp[0], "\\u") {
				tmp[0] = strings.Replace(tmp[0], "\\", "\\\\", -1)
				tmp[0] = strings.Replace(tmp[0], "\\\\u", "\\u", -1)
				pattern, _ = strconv.Unquote(`"` + tmp[0] + `"`)
			} else {
				pattern = tmp[0]
			}
			log.Println("pattern", pattern)
			reg := regexp.MustCompile(pattern)
			apos := reg.FindAllStringSubmatchIndex(content, -1)
			if len(apos) > 0 {
				pos := apos[0]
				for k, p := range posm {
					if len(pos) > p {
						if pos[p] == -1 || pos[p+1] == -1 {
							continue
						}
						val := content[pos[p]:pos[p+1]]
						if sign == -1 {
							rep[k] = "-" + val
						} else {
							rep[k] = val
						}
					}
				}
			}
		}
	}, func(err interface{}) {
		rep["err"] = fmt.Sprint(err)
	})
	return rep
}

func checkAuditReg(content, ruleText string) map[string]interface{} {
	rep := map[string]interface{}{}
	qu.Try(func() {
		var pattern string
		if strings.Contains(ruleText, "\\u") {
			ruleText = strings.Replace(ruleText, "\\", "\\\\", -1)
			ruleText = strings.Replace(ruleText, "\\\\u", "\\u", -1)
			pattern, _ = strconv.Unquote(`"` + ruleText + `"`)
		} else {
			pattern = ruleText
		}
		log.Println("pattern", pattern)
		reg := regexp.MustCompile(pattern)
		rep[pattern] = reg.MatchString(content)
	}, func(err interface{}) {
		rep["err"] = fmt.Sprint(err)
	})
	return rep
}

//lua脚本前置过滤验证
func checkPreScript(code, name, infoid, script string) map[string]interface{} {
	doc, _ := Mgo.FindById("bidding", infoid, extract.Fields)
	j, _, _ := extract.PreInfo(*doc)
	delete(*j.Data, "contenthtml")
	lua := ju.LuaScript{Code: code, Name: name, Doc: *j.Data, Script: script}
	lua.Block = j.Block
	rep := lua.RunScript("pre")
	return rep
}

//lua脚本通用后置过滤验证
func checkBackScript(table, code, name, version, infoid, script string, alone bool) interface{} {
	defer qu.Catch()
	vsion, _ := Mgo.FindOne("version", `{"version":"`+version+`"}`)
	e := &extract.ExtractTask{}
	e.IsRun = true
	e.TaskInfo = &extract.TaskInfo{Version: qu.ObjToString((*vsion)["s_version"]), VersionId: qu.BsonIdToSId((*vsion)["_id"]), TestLua: true}
	e.InitSite()
	e.InitRulePres()
	e.InitPkgCore()
	e.InitRuleBacks(false)
	e.InitRuleBacks(true)
	e.InitRuleCore(false)
	e.InitRuleCore(true)
	e.InitTag(false)
	e.InitTag(true)
	tmp, _ := Mgo.FindById("bidding", infoid, extract.Fields)
	j, _, _ := extract.PreInfo(*tmp)
	doc := *j.Data
	//全局前置规则,结果覆盖doc属性
	for _, v := range e.RulePres {
		doc = extract.ExtRegPre(doc, j, v, e.TaskInfo)
	}
	//抽取规则
	if j.CategorySecond == "" {
		for _, vc1 := range e.RuleCores[j.Category] {
			for _, vc := range vc1 {
				tmp := ju.DeepCopy(doc).(map[string]interface{})
				//是否进入逻辑
				if !ju.Logic(vc.LuaLogic, tmp) {
					continue
				}
				//抽取-前置规则
				for _, v := range vc.RulePres {
					tmp = extract.ExtRegPre(tmp, j, v, e.TaskInfo)
				}
				//抽取-规则
				extract.ExtRuleCore(tmp, e, vc, j, false)
			}
		}
	} else {
		for _, vc1 := range e.RuleCores[j.Category+"_"+j.CategorySecond] {
			for _, vc := range vc1 {
				tmp := ju.DeepCopy(doc).(map[string]interface{})
				//是否进入逻辑
				if !ju.Logic(vc.LuaLogic, tmp) {
					continue
				}
				//抽取-前置规则
				for _, v := range vc.RulePres {
					tmp = extract.ExtRegPre(tmp, j, v, e.TaskInfo)
				}
				//抽取-规则
				extract.ExtRuleCore(tmp, e, vc, j, false)
			}
		}
	}

	result := extract.GetResultMapForLua(j)
	lua := ju.LuaScript{Code: code, Name: name, Result: result, Script: script}
	lua.Block = j.Block
	extinfo := lua.RunScript("back")
	if !alone {
		return extinfo
	} else {
		if table == "rule_back" {
			return extinfo
		} else {
			ru, _ := Mgo.FindOne("rule_logicback", `{"s_code":"`+code+`"}`)
			pid := (*ru)["pid"].(string)
			tmp, _ := Mgo.FindById("versioninfo", pid, `{"s_field":1}`)
			s_field := (*tmp)["s_field"].(string)
			return extinfo[s_field]
		}
	}
}

//lua脚本抽取验证
func checkCoreScript(code, name, infoid, script string) interface{} {
	doc, _ := Mgo.FindById("bidding", infoid, extract.Fields)
	j, _, _ := extract.PreInfo(*doc)
	delete(*j.Data, "contenthtml")
	lua := ju.LuaScript{Code: code, Name: name, Doc: *j.Data, Script: script}
	lua.Block = j.Block
	rep := lua.RunScript("core")
	return rep
}

//lua清理脚本测试
func checkClearScript(code, name, resultcoll, _id, script string) interface{} {
	doc, _ := Mgo.FindById(resultcoll, _id, extract.Fields2)
	data := elastic.Get(qu.ObjToString(ju.Config["mergetablealias"]), qu.ObjToString(ju.Config["mergetable"]), `{"query":{"term":{"list.infoid":"`+_id+`"}}}`)
	kvMap := make(map[string][]map[string]interface{})
	if len(*data) > 0 {
		list := (*data)[0]["list"].([]interface{})
		listArr := qu.ObjArrToMapArr(list)
		kvMap["list"] = listArr
	}
	lua := ju.LuaScript{Code: code, Name: name, Doc: *doc, Script: script, KvMap: kvMap}
	clearResult := lua.ClearRunScript() //清理后结果
	return clearResult
}
