package consumer

import (
	"encoding/json"
	"fmt"
	"git.quantgroup.cn/DevOps/enoch/service/data"
	"git.quantgroup.cn/DevOps/enoch/service/end_points"
	"github.com/gomodule/redigo/redis"
	"github.com/influxdata/influxdb/client/v2"
	"github.com/vrg0/go-common/logger"
	"strings"
	"time"
)

type BraveMessageHandler struct {
}

var httpMethod = map[string]string{
	"get": "", "GET": "", "post": "", "options": "", "put": "", "delete": "", "head": "",
}

func (BraveMessageHandler) MsgProcess(msg string) {

	traceMsg := make([]end_points.TraceMsg, 3) //[]TraceMsg{}
	err := json.Unmarshal([]byte(msg), &traceMsg)
	if err != nil {
		logger.Error("brave 解析msg失败：", err)
	}
	msgInfluxProcess(traceMsg)
}
func (BraveMessageHandler) Destroy() {
	if len(pointSlice) > 0 {
		logger.Info("braveMessageHandler 提交本地缓存数据：", len(pointSlice))
		batchWrite(pointSlice)
	}
}

var pointSlice = make([]*client.Point, 0, batchSize)

func msgInfluxProcess(traceMsgs []end_points.TraceMsg) {

	for _, traceMsg := range traceMsgs {

		if traceMsg.Kind != "SERVER" {
			continue
		}
		path := traceMsg.Name
		if _, ok := httpMethod[path]; ok {
			path = traceMsg.Tags.HttpMethod + " " + path
		}

		path = strings.ToLower(path)

		sysName := traceMsg.LocalEndpoint.ServiceName

		fields := make(map[string]interface{})
		fields["duration"] = traceMsg.Duration / 1000
		fields["traceId"] = traceMsg.TraceId
		bytes, err := json.Marshal(traceMsg)

		msg := string(bytes)

		fields["msg"] = msg

		tags := make(map[string]string)
		tags["sys_name"] = sysName
		tags["path"] = path
		tags["host"] = traceMsg.LocalEndpoint.Ipv4

		if err != nil {
			logger.Fatal(err)
		}

		unix := time.Unix(0, traceMsg.Timestamp*1000)
		if len(pointSlice) == batchSize {
			go batchWrite(pointSlice)
			pointSlice = make([]*client.Point, 0, batchSize)
		}

		point, _ := client.NewPoint("trace_info", tags, fields, unix)
		pointSlice = append(pointSlice, point)

		if err != nil {
			logger.Fatal(err, msg)
		}
	}

}

func Duration(day string, fun func(sysName string, durations map[string]string)) {

	conn := data.Pool.Get()
	defer func() { _ = conn.Close() }()
	matchPattern := "duration*" + day
	reply, err := redis.Values(conn.Do("scan", 0, "match", matchPattern, "count", 10000))
	if err != nil {
		fmt.Print("Scan 扫描key出错", err)
	}

	redisKeys := reply[1].([]interface{})
	for _, redisKey := range redisKeys {

		reply2, err := redis.StringMap(conn.Do("zrevrangebyscore", redisKey, "+inf", 200000, "withscores"))
		if err != nil {
			fmt.Print("获取出错了", err)
		}
		fun(string(redisKey.([]uint8)), reply2)
	}

}

func Counter(day string, fun func(sysName string, durations map[string]string)) {
	conn := data.Pool.Get()
	defer func() { _ = conn.Close() }()
	matchPattern := "counter*" + day
	reply, err := redis.Values(conn.Do("scan", 0, "match", matchPattern, "count", 10000))
	if err != nil {
		fmt.Print("Scan 扫描key出错", err)
	}
	redisKeys := reply[1].([]interface{})
	for _, redisKey := range redisKeys {

		reply2, err := redis.StringMap(conn.Do("zrevrange", redisKey, 0, 300, "withscores"))
		if err != nil {
			fmt.Print("获取出错了", err)
		}
		fun(string(redisKey.([]uint8)), reply2)
	}
}
