package points

import (
	"encoding/json"
	"git.quantgroup.cn/DevOps/enoch/pkg/glog"
	"github.com/influxdata/influxdb/client/v2"
	"github.com/vrg0/go-common/util"
	"strings"
	"time"
)

type TraceMsg struct {
	TraceId        string         `json:"traceId"`
	Id             string         `json:"id"`
	Kind           string         `json:"kind"`
	Name           string         `json:"name"`
	Timestamp      int64          `json:"timestamp"`
	ParentId       string         `json:"parentId"`
	Duration       int            `json:"duration"`
	LocalEndpoint  localEndpoint  `json:"localEndpoint"`
	RemoteEndpoint remoteEndpoint `json:"remoteEndpoint"`
	Tags           tags           `json:"tags"`
	Shared         bool           `json:"shared"`
}

type localEndpoint struct {
	ServiceName string `json:"serviceName"`
	Ipv4        string `json:"ipv4"`
}
type remoteEndpoint struct {
	Ipv4 string `json:"ipv4"`
	Port int    `json:"port"`
}

type tags struct {
	HttpMethod          string `json:"http.method"`
	HttpPath            string `json:"http.path"`
	MvcControllerClass  string `json:"mvc.controller.class"`
	MvcControllerMethod string `json:"mvc.controller.method"`
}

func TraceBaseInfoToPoint(data []byte) ([]*client.Point, error) {
	rtn := make([]*client.Point, 0)
	traceMsgList := make([]TraceMsg, 0)

	err := json.Unmarshal(data, &traceMsgList)
	if err != nil {
		glog.Error("can not unmarshal json:", data)
		return nil, err
	}

	for _, traceInfo := range traceMsgList {
		tracePoint := buildTraceInfluxMsg(traceInfo)
		if tracePoint != nil {
			rtn = append(rtn, tracePoint)
		}
	}

	return rtn, nil
}

//失败返回nil
func buildTraceInfluxMsg(traceInfo TraceMsg) *client.Point {
	if traceInfo.Kind != "SERVER" {
		return nil
	}

	bytes, err := json.Marshal(traceInfo)
	if err != nil {
		glog.Error("can not marshal traceInfo", traceInfo)
		return nil
	}

	fields := make(map[string]interface{})
	fields["duration"] = traceInfo.Duration / 1000
	fields["traceId"] = traceInfo.TraceId
	fields["msg"] = util.BytesString(bytes)

	tags := make(map[string]string)
	tags["sys_name"] = traceInfo.LocalEndpoint.ServiceName
	tags["path"] = strings.ToLower(traceInfo.Tags.HttpMethod + " " + traceInfo.Tags.HttpPath)
	tags["host"] = traceInfo.LocalEndpoint.Ipv4

	unix := time.Unix(0, traceInfo.Timestamp*1000)
	point, err := client.NewPoint("trace_info", tags, fields, unix)
	if err != nil {
		glog.Error("trace client new point:", err, traceInfo)
		return nil
	}
	return point
}
