package continuous_queries

import (
	"fmt"
	"git.quantgroup.cn/DevOps/enoch/service/conf"
	"git.quantgroup.cn/DevOps/enoch/service/data"
	"git.quantgroup.cn/DevOps/enoch/service/log"
	"net"
	"os"
	"strings"
)

var (
	DROP_CQ_SQL  = "DROP CONTINUOUS QUERY %s ON %s;"
	SHOW_CQ_SQL  = "SHOW CONTINUOUS QUERIES;"
	APDEX_CQ_SAT = "CREATE CONTINUOUS QUERY cq_apdex_sat_%s ON monitor RESAMPLE FOR 1h BEGIN SELECT count(traceId) AS sat INTO monitor.autogen.apdex FROM monitor.autogen.trace_info WHERE sys_name = '%s' AND \"duration\" < %d GROUP BY sys_name, time(1m) fill(0) END;"
	APDEX_CQ_TOL = "CREATE CONTINUOUS QUERY cq_apdex_tol_%s ON monitor RESAMPLE FOR 1h BEGIN SELECT count(traceId) AS tol INTO monitor.autogen.apdex FROM monitor.autogen.trace_info WHERE sys_name = '%s' AND \"duration\" > %d AND \"duration\" < %d GROUP BY sys_name, time(1m) fill(0) END;"
	APDEX_CQ_ALL = "CREATE CONTINUOUS QUERY cq_apdex_all ON monitor RESAMPLE FOR 1h BEGIN SELECT count(traceId) AS ct_all INTO monitor.autogen.apdex FROM monitor.autogen.trace_info GROUP BY sys_name, time(1m) fill(1) END;"
)

func query(dbName string) []string {
	cq := data.QueryMonitor(SHOW_CQ_SQL)
	logger.Info.Println(cq)
	cqName := make([]string, 0)
	for _, row := range cq[0].Series {
		if row.Name == dbName {
			for _, v := range row.Values {
				cqName = append(cqName, v[0].(string))
			}
		}
	}
	return cqName
}

func delete(db string, cqName [] string) bool {
	sql := strings.Builder{}
	for _, name := range cqName {
		sql.WriteString(fmt.Sprintf(DROP_CQ_SQL, name, db))
	}
	rs := data.QueryMonitor(sql.String())
	return rs == nil
}

func create(apdexThreshold conf.ApdexThreshold) {
	sysName := data.QuerySysName()
	logger.Info.Println(sysName)
	sql := strings.Builder{}
	for _, name := range sysName {
		cqName := strings.Replace(name, "-", "_", 10)
		threshold := apdexThreshold.Common
		if c, ok := apdexThreshold.Personal[name]; ok {
			threshold = c
		}
		sql.WriteString(buildSatSql(cqName, name, threshold))
		sql.WriteString(buildTolSql(cqName, name, threshold))
	}
	sql.WriteString(APDEX_CQ_ALL)
	data.QueryMonitor(sql.String())
}

func buildSatSql(cqName string, sysName string, threshold int) string {
	return fmt.Sprintf(APDEX_CQ_SAT, cqName, sysName, threshold)
}

func buildTolSql(cqName string, sysName string, threshold int) string {
	return fmt.Sprintf(APDEX_CQ_TOL, cqName, sysName, threshold, threshold*4)
}

func Load() {
	if !checkIp("172.30.12.22"){
		return
	}
	name := query(data.MONITOR)
	logger.Info.Println("old: ", name)
	delete(data.MONITOR, name)
	create(conf.GlobalConfig.ApdexThreshold)
	name = query(data.MONITOR)
	logger.Info.Println("new: ", name)
}


func checkIp(ip string) bool {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	for _, address := range addrs {
		// 检查ip地址判断是否回环地址
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				logger.Info.Println(ipnet.IP.String())
				return  ipnet.IP.String() == ip
			}
		}
	}
	return false
}