// version
package admin

import (
	. "jy/mongodbutil"
	"jy/util"
	"log"
	"net/http"
	qu "qfw/util"
	"strings"
	"time"

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

func init() {
	Admin.GET("/version", func(c *gin.Context) {
		c.HTML(
			http.StatusOK, "version.html",
			gin.H{},
		)
	})
	Admin.POST("/version/data", func(c *gin.Context) {
		data, _ := Mgo.Find("version", `{"delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
		c.JSON(200, gin.H{"data": data})
	})
	Admin.POST("/version/save", func(c *gin.Context) {
		_id, _ := c.GetPostForm("_id")
		data := GetPostForm(c)
		if _id != "" {
			Mgo.UpdateById("version", _id, map[string]interface{}{"$set": data})
			c.JSON(200, gin.H{"rep": true})
		} else {
			version, _ := c.GetPostForm("version")
			tmp, _ := Mgo.FindOne("version", `{"version":"`+version+`","delete":false}`)
			if len(*tmp) > 0 {
				c.JSON(200, gin.H{"rep": false})
			} else {
				s_pversionid, _ := c.GetPostForm("s_pversionid")
				iscopyfiled, _ := data["iscopyfiled"].(bool)
				data["l_createtime"] = time.Now().Unix()
				s_username := sessions.Default(c).Get("username").(string)
				data["s_username"] = s_username
				data["delete"] = false
				vid := Mgo.Save("version", data)
				if s_pversionid != "" {
					copyComRules(version, s_pversionid, s_username)
				}
				if iscopyfiled {
					list, _ := Mgo.Find("versioninfo", `{"vid":`+s_pversionid+`,"delete":false}`, nil, nil, false, -1, -1)
					log.Println(s_pversionid, len(*list))
					for _, v := range *list {
						delete(v, "_id")
						v["l_createtime"] = time.Now().Unix()
						v["s_username"] = sessions.Default(c).Get("username")
						v["l_lasttime"] = time.Now().Unix()
						v["vid"] = vid
						v["delete"] = false
						pid := Mgo.Save("versioninfo", v)
						s_field := qu.ObjToString(v["s_field"])
						copyFieldRules(vid, pid, s_field, s_pversionid, s_username)
					}
				}
				c.JSON(200, gin.H{"rep": true})
			}
		}
	})
	Admin.POST("/version/use", func(c *gin.Context) {
		_id, _ := c.GetPostForm("_id")
		isuse, _ := c.GetPostForm("isuse")
		if isuse == "true" { //启用确保只有一个版本
			l, _ := Mgo.Find("version", `{"isuse":true}`, nil, nil, false, -1, -1)
			if len(*l) > 0 {
				c.JSON(200, gin.H{"rep": false})
				return
			}
		}
		bisuse := false
		if isuse == "true" {
			bisuse = true
		}
		set := map[string]interface{}{
			"$set": map[string]interface{}{
				"isuse": bisuse,
			},
		}
		b := Mgo.UpdateById("version", _id, set)
		c.JSON(200, gin.H{"rep": b})
	})
	Admin.POST("/version/del", func(c *gin.Context) { //删除版本
		_id, _ := c.GetPostForm("_id")
		s_version, _ := c.GetPostForm("version")
		b := Mgo.UpdateById("version", _id, `{"$set":{"delete":true}}`)
		//b := Mgo.Del("version", `{"_id":"`+_id+`"}`)
		//级联删除
		//刪除属性配置
		//删除逻辑
		//删除属性配置中的前置规则
		//删除属性配置中的抽取规则
		//删除属性配置中的后置规则
		go DelVersionInfo(_id)
		//删除版本的通用前置规则
		go DelRulePre(s_version)
		//删除版本的通用后置规则
		go DelRuleBack(s_version)
		//删除标签库
		go DelTag(s_version)
		//删除版本的通用前置规则
		go DelCleanUp(s_version)
		c.JSON(200, gin.H{"rep": b})
	})
	Admin.GET("/version/info", func(c *gin.Context) {
		vid := c.Query("vid")
		v, _ := Mgo.Find("version", `{}`, `{"_id":-1}`, `{"version":1}`, false, -1, -1)
		c.HTML(
			http.StatusOK, "versioninfo.html",
			gin.H{"vid": vid, "versions": v},
		)
	})
	Admin.POST("/version/infodata", func(c *gin.Context) {
		vid, _ := c.GetPostForm("vid")
		list, _ := Mgo.Find("versioninfo", `{"vid":"`+vid+`","delete":false}`, `{"_id":-1}`, nil, false, -1, -1)
		c.JSON(200, gin.H{"data": list, "vid": vid})
	})
	Admin.POST("/version/infosave", func(c *gin.Context) {
		_id, _ := c.GetPostForm("_id")
		data := GetPostForm(c)
		if _id != "" {
			Mgo.UpdateById("versioninfo", _id, map[string]interface{}{"$set": data})
			c.JSON(200, gin.H{"rep": true})
		} else {
			s_field, _ := c.GetPostForm("s_field")
			vid, _ := c.GetPostForm("vid")
			tmp, _ := Mgo.FindOne("versioninfo", `{"s_field":"`+s_field+`","vid":"`+vid+`","delete":false}`)
			if len(*tmp) > 0 {
				c.JSON(200, gin.H{"rep": false})
			} else {
				data["l_createtime"] = time.Now().Unix()
				data["s_username"] = sessions.Default(c).Get("username")
				data["l_lasttime"] = time.Now().Unix()
				data["delete"] = false
				pid := Mgo.Save("versioninfo", data)
				fromvid, _ := data["s_pversionid"].(string)
				if fromvid != "" {
					copyFieldRules(vid, pid, s_field, fromvid, sessions.Default(c).Get("username").(string))
				}
				c.JSON(200, gin.H{"rep": true})
			}
		}
	})
	Admin.POST("/version/infouse", func(c *gin.Context) {
		_id, _ := c.GetPostForm("_id")
		isuse, _ := c.GetPostForm("isuse")
		b := Mgo.UpdateById("versioninfo", _id, `{"$set":{"isuse":`+isuse+`}}`)
		c.JSON(200, gin.H{"rep": b})
	})
	Admin.POST("/version/infodel", func(c *gin.Context) {
		_id, _ := c.GetPostForm("_id")
		b := Mgo.UpdateById("versioninfo", _id, `{"$set":{"delete":true}}`)
		v, _ := Mgo.FindById("versioninfo", _id, `{"vid":1}`)
		go DelLogic(qu.ObjToString((*v)["vid"]), _id)
		//b := Mgo.Del("versioninfo", `{"_id":"`+_id+`"}`)
		c.JSON(200, gin.H{"rep": b})
	})
}

//克隆版本通用属性
func copyComRules(version, pvid, s_username string) {
	tmp, _ := Mgo.FindById("version", pvid, nil)
	oldversion := (*tmp)["version"].(string)
	//克隆前置规则
	plist, _ := Mgo.Find("rule_pre", `{"s_version":"`+oldversion+`","delete":false}`, nil, nil, false, -1, -1)
	for _, v := range *plist {
		delete(v, "_id")
		v["s_version"] = version
		v["s_code"] = util.GetSyncIndex(getCode(v["s_code"].(string)))
		v["s_username"] = s_username
		v["l_createtime"] = time.Now().Unix()
		v["l_lasttime"] = time.Now().Unix()
		Mgo.Save("rule_pre", v)
	}
	//克隆后置规则
	blist, _ := Mgo.Find("rule_back", `{"s_version":"`+oldversion+`","delete":false}`, nil, nil, false, -1, -1)
	for _, v := range *blist {
		delete(v, "_id")
		v["s_version"] = version
		v["s_code"] = util.GetSyncIndex(getCode(v["s_code"].(string)))
		v["s_username"] = s_username
		v["l_createtime"] = time.Now().Unix()
		v["l_lasttime"] = time.Now().Unix()
		Mgo.Save("rule_back", v)
	}
	//克隆tag
	tlist, _ := Mgo.Find("tag", `{"s_version":"`+oldversion+`","delete":false}`, nil, nil, false, -1, -1)
	for _, v := range *tlist {
		oldId := qu.BsonIdToSId(v["_id"])
		delete(v, "_id")
		v["s_version"] = version
		v["s_creater"] = s_username
		v["l_intime"] = time.Now().Unix()
		newId := Mgo.Save("tag", v) //克隆父标签
		td, _ := Mgo.Find("tagdetailinfo", `{"s_parentid":"`+oldId+`","delete":false}`, nil, nil, false, -1, -1)
		for _, v2 := range *td {
			delete(v2, "_id")
			v2["s_version"] = version
			v2["s_creater"] = s_username
			v2["l_intime"] = time.Now().Unix()
			v2["s_parentid"] = newId
			Mgo.Save("tagdetailinfo", v2) //克隆详细标签
		}
	}
	//克隆函数
	clist, _ := Mgo.Find("cleanup", `{"s_version":"`+oldversion+`","delete":false}`, nil, nil, false, -1, -1)
	for _, v := range *clist {
		delete(v, "_id")
		v["s_version"] = version
		v["s_creater"] = s_username
		v["l_intime"] = time.Now().Unix()
		Mgo.Save("cleanup", v)
	}
}

//克隆版本Field
func copyFieldRules(vid, pid, s_field, oldvid, s_username string) {
	tmp, _ := Mgo.FindOne("versioninfo", `{"vid":"`+oldvid+`","s_field":"`+s_field+`","delete":false}`)
	oldpid := qu.BsonIdToSId((*tmp)["_id"])
	log.Println(s_field, oldvid, oldpid, s_username)
	//克隆逻辑列表
	logic, _ := Mgo.FindOne("rule_logic", `{"vid":"`+oldvid+`","pid":"`+oldpid+`","delete":false}`)
	if len(*logic) > 0 {
		oldsid := qu.BsonIdToSId((*logic)["_id"])
		delete(*logic, "_id")
		(*logic)["vid"] = vid
		(*logic)["pid"] = pid
		(*logic)["l_createtime"] = time.Now().Unix()
		(*logic)["l_lasttime"] = time.Now().Unix()
		(*logic)["s_username"] = s_username
		sid := Mgo.Save("rule_logic", logic)
		//克隆前置规则
		plist, _ := Mgo.Find("rule_logicpre", `{"sid":"`+oldsid+`","delete":false}`, nil, nil, false, -1, -1)
		for _, v := range *plist {
			delete(v, "_id")
			v["vid"] = vid
			v["pid"] = pid
			v["sid"] = sid
			v["s_code"] = util.GetSyncIndex(getCode(v["s_code"].(string)))
			v["s_username"] = s_username
			v["l_createtime"] = time.Now().Unix()
			v["l_lasttime"] = time.Now().Unix()
			Mgo.Save("rule_logicpre", v)
		}
		//克隆抽取规则
		elist, _ := Mgo.Find("rule_logicore", `{"sid":"`+oldsid+`","delete":false}`, nil, nil, false, -1, -1)
		for _, v := range *elist {
			delete(v, "_id")
			v["vid"] = vid
			v["pid"] = pid
			v["sid"] = sid
			v["s_code"] = util.GetSyncIndex(getCode(v["s_code"].(string)))
			v["s_username"] = s_username
			v["l_createtime"] = time.Now().Unix()
			v["l_lasttime"] = time.Now().Unix()
			Mgo.Save("rule_logicore", v)
		}
		//克隆过滤规则
		blist, _ := Mgo.Find("rule_logicback", `{"sid":"`+oldsid+`","delete":false}`, nil, nil, false, -1, -1)
		for _, v := range *blist {
			delete(v, "_id")
			v["vid"] = vid
			v["pid"] = pid
			v["sid"] = sid
			v["s_code"] = util.GetSyncIndex(getCode(v["s_code"].(string)))
			v["s_username"] = s_username
			v["l_createtime"] = time.Now().Unix()
			v["l_lasttime"] = time.Now().Unix()
			Mgo.Save("rule_logicback", v)
		}
	}
}

//获取代码
func getCode(code string) string {
	tmps := strings.Split(code, "_")
	tmp := tmps[:len(tmps)-1]
	return strings.Join(tmp, "_")
}
