package server

import (
	"fmt"

	"github.com/gin-gonic/gin"
	dto "github.com/prometheus/client_model/go"
	"github.com/tidbcloud/serverless-metering/pkg/config"
	"github.com/tidbcloud/serverless-metering/pkg/store"
)

type RcuServer struct {
	addr   string
	engine *gin.Engine
	store  store.RcuStore
}

func NewRcuServer(store store.RcuStore) *RcuServer {
	cfg := config.Global().Server
	engine := gin.Default()
	group := engine.Group("/api/v1/rcu")
	server := &RcuServer{
		addr:   fmt.Sprintf(":%d", cfg.RcuPort),
		engine: engine,
		store:  store,
	}
	group.POST("metrics", server.WriteMetrics)
	group.GET("capacities", server.GetRcuCapacities)
	return server
}

func (s *RcuServer) Start() error {
	return s.engine.Run(s.addr)
}

func (s *RcuServer) WriteMetrics(c *gin.Context) {
	labels := make(map[string]string)
	metricFamilies := &dto.MetricFamily{}
	if err := c.ShouldBindJSON(&metricFamilies); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}
	if err := s.store.WriteMetrics(labels, metricFamilies); err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, gin.H{"status": "ok"})
}

func (s *RcuServer) GetRcuCapacities(c *gin.Context) {
	capacities, err := s.store.ListRcuCapacities()
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, capacities)
}
