package web

import (
	"classification"
	"fmt"
	"html/template"
	"net/http"
	"qfw/util"
	"regexp"
	"strings"
	"task"
	"time"
	. "tools"
	u "util"

	"go.mongodb.org/mongo-driver/bson/primitive"
)

func GetParent(s_pid, coll string, pm *map[string]interface{}) {
	defer Catch()
	if s_pid != "" {
		//可能有多个父类
		ids := strings.Split(s_pid, ",")
		idsmap := []map[string]interface{}{}
		for _, val := range ids {
			idsmap = append(idsmap, map[string]interface{}{
				"_id": u.StringTOBsonId(val),
			})
		}
		class, b := MgoClass.Find(coll, &map[string]interface{}{
			"$or": idsmap,
		}, nil, `{"_id":1,"s_name":1,"s_pid":1,"s_classid":1}`, false, 0, 10)
		if b && class != nil && len(*class) > 0 {
			for _, cla := range *class {
				pid := util.ObjToString(cla["s_pid"])
				GetParent(pid, coll, &cla)
			}
			(*pm)["p"] = class
		}
	}
	return
}

func rule(w http.ResponseWriter, r *http.Request) {
	defer Catch()
	if CheckSession(w, r) {
		id := r.FormValue("id")
		class, _ := MgoClass.FindById(COLL_CLASS, id, `{"_id":1,"s_name":1,"s_pid":1}`)
		//级联查询,往上查
		if class != nil && *class != nil {
			pid := util.ObjToString((*class)["s_pid"])
			if pid != "" {
				GetParent(pid, COLL_CLASS, class)
			}
		}
		ss, _ := Store.Get(r, SN)
		data := map[string]interface{}{"s_name": ss.Values["s_name"]}
		//查询配置规则
		res, _ := MgoClass.Find(COLL_RULE, `{"s_classid":"`+id+`"}`, `{"i_order":1}`, nil, false, 0, 200)
		Finds := map[string]interface{}{}
		for _, tmpres := range *res {
			rpid := util.ObjToString(tmpres["s_pid"])
			if rpid != "" {
				if Finds[rpid] != nil {
					tmpres["p"] = Finds[rpid]
				} else {
					GetParent(rpid, COLL_RULE, &tmpres)
					Finds[rpid] = tmpres["p"]
				}
			}
		}
		data["rule"] = res
		data["class"] = class
		ExecuteTpl("rule.html", &data, w)
	} else {
		http.Redirect(w, r, "/", http.StatusFound)
	}
}

func rulesave(w http.ResponseWriter, r *http.Request) {
	defer Catch()
	res := JSON{}
	var s_ruleArr []string
	var s_detailRuleArr []string
	var s_notRuleArr []string
	if CheckSession(w, r) {
		_id := r.FormValue("_id")
		s_classid := r.FormValue("s_classid")
		s_name := r.FormValue("s_name")
		s_code := r.FormValue("s_code")
		rule := r.FormValue("s_rule")
		rule = regexp.MustCompile("\\n|\\s+").ReplaceAllString(rule, "")
		s_rule := strings.Split(rule, "'")
		//fmt.Println(len(s_rule), "s_rule-------", s_rule)
		s_ruleArr = getRuleArr(s_rule)

		detailrule := r.FormValue("s_detailrule")
		if detailrule != "" {
			detailrule = regexp.MustCompile("\\n|\\s+").ReplaceAllString(detailrule, "")
			s_detailrule := strings.Split(detailrule, "'")
			fmt.Println(len(s_detailrule), "s_detailrule-------", s_detailrule)
			s_detailRuleArr = getRuleArr(s_detailrule)
		}

		notrule := r.FormValue("s_notrule")
		if notrule != "" {
			notrule = regexp.MustCompile("\\n|\\s+").ReplaceAllString(notrule, "")
			s_notrule := strings.Split(notrule, "'")
			fmt.Println(len(s_notrule), "s_notrule-------", s_notrule)
			s_notRuleArr = getRuleArr(s_notrule)
		}

		//s_rule := strings.Split(rule, ",")
		s_pid := r.FormValue("s_pid")
		s_rule_prerule := r.FormValue("s_rule_prerule")
		//fmt.Println(s_ruleArr, s_code, s_classid, s_rule_prerule, s_pid, GetOrder("rule"))
		if _id == "" {
			session, _ := Store.Get(r, SN)
			ids := MgoClass.Save(COLL_RULE, map[string]interface{}{
				"s_name":         s_name,
				"s_rule":         s_ruleArr,
				"s_detailrule":   s_detailRuleArr,
				"s_notrule":      s_notRuleArr,
				"s_code":         s_code,
				"s_classid":      s_classid,
				"l_lasttime":     time.Now().Unix(),
				"l_date":         time.Now().Unix(),
				"s_user":         session.Values["s_name"],
				"i_status":       0,
				"s_pid":          s_pid,
				"i_order":        GetOrder("rule"),
				"s_rule_prerule": s_rule_prerule,
			})
			if ids != "" {
				//go task.InitRule() //重新初始化任务
				res.Status = true
				res.Msg = "保存成功"
			} else {
				res.Msg = "保存失败"
			}
		} else {
			b := MgoClass.Update(COLL_RULE, `{"_id":"`+_id+`"}`, map[string]interface{}{
				"$set": map[string]interface{}{
					"s_name":         s_name,
					"s_code":         s_code,
					"s_rule":         s_ruleArr,
					"s_detailrule":   s_detailRuleArr,
					"s_notrule":      s_notRuleArr,
					"l_lasttime":     time.Now().Unix(),
					"s_pid":          s_pid,
					"s_rule_prerule": s_rule_prerule,
				},
			}, false, false)
			if b {
				//go task.InitRule() //重新初始化任务
				res.Status = true
				res.Msg = "保存成功"
			} else {
				res.Msg = "保存失败"
			}
		}
	} else {
		res.Msg = "重新登陆"
	}
	WriteJSON(w, res)
}

func ruledelete(w http.ResponseWriter, r *http.Request) {
	defer Catch()
	res := JSON{}
	if CheckSession(w, r) {
		_id := r.FormValue("_id")
		if _id == "" {
			res.Msg = "id不能为空"
		} else {
			b := MgoClass.Del(COLL_RULE, `{"_id":"`+_id+`"}`)
			if b {
				//go task.InitRule() //重新初始化任务
				res.Status = true
				res.Msg = "删除成功"
			} else {
				res.Msg = "删除失败"
			}
		}
	} else {
		res.Msg = "重新登陆"
	}
	WriteJSON(w, res)
}

//根据类id查找规则！！！用来选择
func getList(w http.ResponseWriter, r *http.Request) {
	defer Catch()
	res := JSON{}
	if CheckSession(w, r) {
		id := r.FormValue("id")
		if id == "" {
			res.Msg = "内容不能为空"
		} else {
			//先找类
			ids := strings.Split(id, ",")
			ids2 := make([]string, len(ids))
			idsmap := []map[string]interface{}{}
			for n, val := range ids {
				idsmap = append(idsmap, map[string]interface{}{
					"_id": u.StringTOBsonId(val),
				})
				ids2[n] = fmt.Sprintf(`{"s_classid":"%s"}`, val)
			}
			class, _ := MgoClass.Find(COLL_CLASS, &map[string]interface{}{
				"$or": idsmap,
			}, nil, `{"s_name":1}`, false, 0, 10)
			rule, _ := MgoClass.Find(COLL_RULE, fmt.Sprintf(`{"$or":[%s]}`, strings.Join(ids2, ",")), `{"i_order":1}`, `{"s_name":1,"s_code":1,"s_classid":1}`, false, 0, 200)
			for _, ru := range *rule {
				for _, c := range *class {
					if u.BsonIdToSId(c["_id"]) == ru["s_classid"] {
						ru["s_name"] = fmt.Sprintf("%s[%s]", ru["s_name"], c["s_name"])
					}
				}
			}
			res.Data = rule
			res.Status = true
		}
	} else {
		res.Msg = "重新登陆"
	}
	WriteJSON(w, res)
}

//测试rule启动
func rulerun(w http.ResponseWriter, r *http.Request) {
	defer Catch()
	data := map[string]interface{}{
		"b":     false,
		"rules": "",
		"text":  "",
		"pos":   0,
	}
	if CheckSession(w, r) {
		testname := r.FormValue("testname")
		s_con := r.FormValue("s_con")
		_id := r.FormValue("_id")
		s_ruletype := r.FormValue("s_ruletype")
		if _id == "" || s_con == "" {
			data["text"] = "内容不能为空"
		} else {
			rule, _ := MgoClass.FindById(COLL_RULE, _id, `{"s_rule":1,"s_detailrule":1,"s_rule_prerule":1}`)
			s_rule := []string{}
			if s_ruletype == "rule" {
				s_rule = ObjArrToStringArr((*rule)["s_rule"].(primitive.A))
			} else {
				if s_detailrule, ok := (*rule)["s_detailrule"].(primitive.A); ok && len(s_detailrule) > 0 {
					s_rule = ObjArrToStringArr(s_detailrule)
				}
			}
			s_con = task.PreFilter(s_con, util.ObjToString((*rule)["s_rule_prerule"])) //对文本先进行前置过滤
			text := ""
			rules := [][]string{}
			pos := 0
			b := false
			if testname == "test1" {
				text, rules, pos, b = classification.ClassificationText(s_con, classification.AnalyRules(s_rule))
			} else {
				rulearr := [][]string{}
				b_reg := false
				i_rule := task.DealRules((*rule)["s_rule"].(primitive.A))       //初始化规则
				b, b_reg, rulearr, pos = task.DFAAnalyRulesTest2(s_con, i_rule) //是否匹配,匹配成功的规则
				text, rules = classification.ClassText(b, b_reg, pos, s_rule, rulearr, s_con)
			}
			data["b"] = b
			data["pos"] = pos + 1
			data["rules"] = func() template.HTML {
				ts := []string{}
				for ppos, s := range rules {
					ts = append(ts, fmt.Sprintf("<p>%d.%s</p>", ppos+1, strings.Join(s, "")))
				}
				return template.HTML(strings.Join(ts, ""))
			}()
			data["text"] = template.HTML(text)
			//fmt.Println("data---", data)
		}
	} else {
		data["text"] = "重新登陆"
	}
	ExecuteTpl("checkres.html", &data, w)
}

func Shift(w http.ResponseWriter, r *http.Request) {
	defer Catch()
	res := JSON{}
	if CheckSession(w, r) {
		str := r.FormValue("str")
		strs := strings.Split(str, ",")
		if str == "" || len(strs) != 4 {
			res.Msg = "请求不能为空或格式不正确"
		} else {
			if MgoClass.Update(COLL_RULE, `{"_id":"`+strs[0]+`"}`, &map[string]interface{}{
				"$set": map[string]interface{}{
					"i_order": IntAll(strs[3]),
				},
			}, false, false) {
				MgoClass.Update(COLL_RULE, `{"_id":"`+strs[2]+`"}`, &map[string]interface{}{
					"$set": map[string]interface{}{
						"i_order": IntAll(strs[1]),
					},
				}, false, false)
				res.Status = true
			} else {
				res.Msg = "移动失败..."
			}

		}
	} else {
		res.Msg = "重新登陆"
	}
	WriteJSON(w, res)
}

func getRuleArr(rule []string) (tmpArr []string) {
	for k, r := range rule {
		if k%2 == 1 { //奇数为正则
			r = "'" + r + "'" //为正则加上''
			if r != "" {
				tmpArr = append(tmpArr, r)
			}
		} else {
			fr := strings.Split(r, ",")
			for _, frs := range fr {
				if frs != "" {
					tmpArr = append(tmpArr, frs)
				}
			}
		}
	}
	return
}
