// distribution 分布式抽取管理
package distribution

import (
	"encoding/json"
	. "jy/admin"
	"jy/cluster"
	"jy/extract"
	db "jy/mongodbutil"
	ju "jy/util"
	"log"
	mu "mfw/util"
	"net"
	qu "qfw/util"
	"time"

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

func init() {
	Admin.GET("/distribution", func(c *gin.Context) {
		c.HTML(200, "distribution.html", nil)
	})

	//获取ecs列表
	Admin.POST("/distribution/ecslist", func(c *gin.Context) {
		data, _ := db.Mgo.Find("ecs", `{}`, `{"_id":-1}`, nil, false, -1, -1)
		c.JSON(200, gin.H{"data": data})
	})

	//申请ecs实例、id划段
	Admin.POST("/distribution/runInstances", func(c *gin.Context) {
		s_table, _ := c.GetPostForm("s_table")
		instanceid, _ := c.GetPostForm("instanceid")
		if s_table != "" { //id划段
			sdate, _ := c.GetPostForm("s_date")
			edate, _ := c.GetPostForm("e_date")
			log.Println(s_table, sdate, edate)
			IdsRange(s_table, sdate, edate)
		} else if instanceid != "" { //实例自动释放时间
			hours, _ := c.GetPostForm("hours")
			hour := qu.IntAll(hours)
			if hour > 0 {
				log.Println(instanceid, hour)
				cluster.ModifyInstanceAutoReleaseTime(instanceid, hour)
			}
		} else { //申请ecs实例
			TaskName, _ := c.GetPostForm("s_name")
			s_computer, _ := c.GetPostForm("s_computer")
			s_flow, _ := c.GetPostForm("s_flow")
			num, _ := c.GetPostForm("i_num")
			hours, _ := c.GetPostForm("i_hours")
			cluster.RunInstances(TaskName, s_computer, s_flow, qu.IntAll(num), qu.IntAll(hours))
		}
		c.JSON(200, gin.H{"rep": true})
	})

	//更新ecs实例状态
	Admin.POST("/distribution/upstatus", func(c *gin.Context) {
		cluster.DescribeInstances()
		c.JSON(200, gin.H{"rep": true})
	})
	//单实例任务
	Admin.POST("/distribution/continueExecution", func(c *gin.Context) {
		qu.Catch()
		InstanceId, _ := c.GetPostForm("InstanceId")
		tmp, b := db.Mgo.FindOneByField("ecs", `{"InstanceId":"`+InstanceId+`"}`, `{"ip_nw":1,"lastId":1,"extask":1}`)
		if b && tmp != nil {
			ip := ""
			ip = qu.ObjToString((*tmp)["ip_nw"])
			by, _ := json.Marshal(map[string]interface{}{
				"ip":         ip,
				"InstanceId": InstanceId,
				"stype":      "distributed",
			})
			err := extract.Udpclient.WriteUdp(by, mu.OP_TYPE_DATA, &net.UDPAddr{
				IP:   net.ParseIP(ip),
				Port: qu.IntAll(ju.Config["udpport"]),
			})
			if err != nil {
				log.Println(err)
				c.JSON(200, gin.H{"rep": true})
				return
			}
			c.JSON(200, gin.H{"rep": true})
			return
		}
		c.JSON(200, gin.H{"rep": false})
	})
	//释放ecs实例
	Admin.POST("/distribution/deleteInstance", func(c *gin.Context) {
		InstanceId, _ := c.GetPostForm("InstanceId")
		cluster.DeleteInstance(InstanceId)
		c.JSON(200, gin.H{"rep": true})
	})
	//数据库删除ecs实例
	Admin.POST("/distribution/deleteInstancedb", func(c *gin.Context) {
		InstanceId, _ := c.GetPostForm("InstanceId")
		b := db.Mgo.Del("ecs", `{"InstanceId":"`+InstanceId+`"}`)
		c.JSON(200, gin.H{"rep": b})
	})

	//部署
	Admin.POST("/distribution/deploy", func(c *gin.Context) {
		list, _ := db.Mgo.Find("ecs", `{"Status":"Running"}`, nil, nil, false, -1, -1)
		ch := make(chan bool, 5)
		for _, v := range *list {
			time.Sleep(1 * time.Second)
			ch <- true
			go func(v map[string]interface{}) {
				ip := qu.ObjToString(v["ip_nw"])
				id := qu.ObjToString(v["InstanceId"])
				log.Println("部署", ip, id)
				cluster.RunSsh(ip, cluster.Password, 22)
				db.Mgo.Update("ecs", `{"ip_nw":"`+ip+`"}`,
					map[string]interface{}{
						"$set": map[string]interface{}{
							"extstatus": "deploy",
						},
					}, true, false)
				<-ch
			}(v)
		}
		c.JSON(200, gin.H{"rep": true})
	})

	Admin.POST("/distribution/deployone", func(c *gin.Context) {
		InstanceId, _ := c.GetPostForm("InstanceId")
		v, b := db.Mgo.FindOneByField("ecs", `{"InstanceId":"`+InstanceId+`"}`, `{"ip_nw":1,"InstanceId":1}`)
		log.Println(b, InstanceId)
		if b {
			ip := qu.ObjToString((*v)["ip_nw"])
			id := qu.ObjToString((*v)["InstanceId"])
			db.Mgo.Update("ecs", `{"ip_nw":"`+ip+`"}`,
				map[string]interface{}{
					"$set": map[string]interface{}{
						"extstatus": "",
					},
				}, true, false)
			log.Println("部署", ip, id)
			cluster.RunSsh(ip, cluster.Password, 22)
			db.Mgo.Update("ecs", `{"ip_nw":"`+ip+`"}`,
				map[string]interface{}{
					"$set": map[string]interface{}{
						"extstatus": "deploy",
					},
				}, true, false)

		}
		c.JSON(200, gin.H{"rep": true})
	})

	//分发任务
	Admin.POST("/distribution/rangetask", func(c *gin.Context) {
		num := RunEcsTask()
		log.Println("任务分发完成", num)
		c.JSON(200, gin.H{"rep": true})
	})
}
