package opsapi

import (
	"net/http"

	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	docs "github.com/tidbcloud/observability/api/opsserverswagger"
	"github.com/tidbcloud/observability/pkg/common/constants"
	commonInterceptor "github.com/tidbcloud/observability/pkg/common/interceptor"
	"github.com/tidbcloud/observability/pkg/common/message"
	"github.com/tidbcloud/observability/pkg/regionalapi/apiinterceptor"
)

func route(g *gin.Engine) {
	// enable pprof
	pprof.Register(g)

	// support swagger
	docs.SwaggerInfo.BasePath = "/ops/api/v1"
	swagger := g.Group("/swagger")
	{
		swagger.GET("/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	}

	g.GET("/health", ServiceHealth)

	// api
	apiV1 := g.Group("/ops/api/v1")
	// TODO: add authn & authz for ops api
	apiV1.Use(commonInterceptor.Log, gin.CustomRecovery(commonInterceptor.Recover))
	{
		apiV1.GET("/", ServiceInfo)

		// VM Cluster CRUD operations (legacy - specific to VM clusters)
		apiV1.POST("/vmclusters", CreateVMCluster)
		apiV1.GET("/vmclusters", ListVMClusters)
		apiV1.GET("/vmclusters/:vmclusterId", GetVMCluster)
		apiV1.PUT("/vmclusters/:vmclusterId", UpdateVMCluster)
		apiV1.DELETE("/vmclusters/:vmclusterId", DeleteVMCluster)

		// General HelmRelease CRUD operations
		apiV1.POST("/helmreleases", CreateHelmRelease)
		apiV1.GET("/helmreleases", ListHelmReleases)
		apiV1.POST("/helmreleases/diff", DiffHelmRelease)
		apiV1.GET("/helmreleases/:name", GetHelmRelease)
		apiV1.PUT("/helmreleases/:name", UpdateHelmRelease)
		apiV1.DELETE("/helmreleases/:name", DeleteHelmRelease)

		// Upgrade operations
		apiV1.POST("/upgradeOperations", CreateUpgradeOperation)
		apiV1.POST("/upgradeOperations/dry-run", DryRunUpgradeOperation)
		apiV1.GET("/upgradeOperations", ListUpgradeOperations)
		apiV1.GET("/upgradeOperations/:id", GetUpgradeOperation)
		apiV1.PUT("/upgradeOperations/:id/pause", PauseUpgradeOperation)
		apiV1.PUT("/upgradeOperations/:id/resume", ResumeUpgradeOperation)
		apiV1.DELETE("/upgradeOperations/:id", DeleteUpgradeOperation)

		// Node groups (cluster upgrade related)
		apiV1.GET("/nodeGroups", GetNodeGroups)

		// Addons (cluster upgrade related)
		apiV1.GET("/addons", ListAddons)

		// update alertmanager basic auth
		apiV1.PUT("/alert-auth", UpdateBasicAuth)
	}

}

// ServiceInfo
// @Summary get service info
// @Description get service info
// @Tags service
// @Accept json
// @Produce json
// @Success 200 {object} message.Result{data=message.GetServiceInfoResp}
// @Failure 500 {object} message.Result
// @Router / [get]
func ServiceInfo(c *gin.Context) {
	apiinterceptor.Succeed(c, http.StatusOK, message.GetServiceInfoResp{
		ServiceName: constants.ObservabilityOpsServer,
	})
}

// ServiceHealth
// @Summary get service health
// @Description get service health
// @Tags service
// @Accept json
// @Produce json
// @Success 200 {object} message.Result{data=message.GetServiceHealthResp}
// @Failure 500 {object} message.Result
// @Router /health [get]
func ServiceHealth(c *gin.Context) {
	apiinterceptor.Succeed(c, http.StatusOK, message.GetServiceHealthResp{
		ServiceHealth: true,
	})
}
