package rest

import (
	"context"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/errors"
	"github.com/pingcap/log"
	promsvc "github.com/tidbcloud/metrics-integration/pipeline/internal/service/prometheus"
	"go.uber.org/zap"
)

var (
	//errAPIKeyNotFound = errors.NotFoundf("api key not found")
	errTokenNotFound = errors.NotFoundf("token not found")
	errInvalidToken  = errors.BadRequestf("invalid token")
)

type GetMetricsReq struct {
	ClusterID uint64 `uri:"cluster_id" binding:"required"`
}

func PingHandler(c *gin.Context) {
	success(c, "pong", http.StatusOK)
}

func success(c *gin.Context, result interface{}, code int) {
	c.JSON(code, result)
}

func fail(c *gin.Context, msg string, code int) {
	c.JSON(code, gin.H{"code": code, "message": msg})
}

func HandleClusterMetrics(service *promsvc.Manager) gin.HandlerFunc {
	return func(c *gin.Context) {
		// Auth Part
		token, err := getToken(c)
		if err != nil {
			fail(c, err.Error(), http.StatusUnauthorized)
			c.Abort()
			return
		}

		req := GetMetricsReq{}
		if err := c.BindUri(&req); err != nil {
			fail(c, err.Error(), http.StatusBadRequest)
			return
		}

		clusterID := req.ClusterID

		ctx := context.Background()
		clusterConfig, err := service.ValidClusterTokenAndGetConfig(ctx, clusterID, token)
		if err != nil {
			if errors.Cause(err) == errTokenNotFound {
				fail(c, err.Error(), http.StatusUnauthorized)
			} else if errors.Cause(err) == errInvalidToken {
				fail(c, err.Error(), http.StatusUnauthorized)
			} else {
				fail(c, err.Error(), http.StatusInternalServerError)
			}
			return
		}
		data, err := service.QueryClusterMetrics(ctx, clusterConfig)
		if err != nil {
			fail(c, err.Error(), http.StatusInternalServerError)
			return
		}

		log.Debug("HandleProjectMetrics", zap.String("requestUri", c.Request.RequestURI), zap.ByteString("response", data))
		c.Data(http.StatusOK, "text/plain; version=0.0.4", data)
	}
}
