package api

import (
	"strconv"
	"tcidm/docs"
	"tcidm/internal/controller"
	regionalImport "tcidm/internal/controller/regional_import_service"
	regionalUtil "tcidm/internal/controller/regional_util_service"
	"tcidm/internal/controller/regional_util_service/proxy"
	"tcidm/metrics"
	"time"

	"github.com/gin-gonic/gin"
	swaggerfiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

// @Time    : 2024/8/21 14:27
// @Author  : lvhongmeng

func Routers(ginEng *gin.Engine) {
	ginEng.Any(
		"/healthz", func(c *gin.Context) {
			c.Status(200)
		},
	)

	// Error
	routeError(ginEng)

	// Cors
	routeCors(ginEng)

	// Metric
	ginEng.Use(Metric())

	// Real REST-API registry
	routeRestAPI(ginEng)
}

// Metric middleware
func Metric() gin.HandlerFunc {
	return func(c *gin.Context) {
		tBegin := time.Now()
		c.Next()

		duration := time.Since(tBegin).Milliseconds()
		path := c.FullPath()
		status := strconv.Itoa(c.Writer.Status())
		metrics.HTTPReqDuration.WithLabelValues(c.Request.Method, path, status).Observe(float64(duration))
	}
}

func routeError(router *gin.Engine) {
	router.Use(APIErrorJSONReporter())
}

func routeCors(router *gin.Engine) {
	router.Use(Cors())
}

func routeRestAPI(router *gin.Engine) {
	//swag init -g cmd/regional_tcidm_service/main.go --parseDependency --parseInternal
	docs.SwaggerInfo.BasePath = "/api/v1/tcidm"
	router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
	regionalService := router.Group("/api/v1/tcidm")
	{
		// only for import
		// regionalService.GET("/import/helloworld", regionalImport.Hello)
		regionalService.GET("/privatelinkendpoint/cr", controller.GetPrivateLinkEndpointCR)
		regionalService.POST("/privatelinkendpoint/cr", controller.CreatePrivateLinkEndpointCR)
		regionalService.DELETE("/privatelinkendpoint/cr", controller.DeletePrivateLinkEndpointCR)

		regionalService.GET("/dmjob/cr", controller.GetDMJobCR)
		regionalService.POST("/dmjob/cr", controller.CreateDMJobCR)
		regionalService.PUT("/dmjob/cr", controller.UpdateDMJobCR)
		regionalService.DELETE("/dmjob/cr", controller.DeleteDMJobCR)

		regionalService.GET("/import/cr", regionalImport.GetImportCR)
		regionalService.POST("/import/cr", regionalImport.CreateImportCR)
		regionalService.DELETE("/import/cr", regionalImport.DeleteImportCR)
		regionalService.POST("/import/progress", regionalImport.GetImportProgress)
		regionalService.POST("/import/precheck", regionalImport.ImportPrecheck)
		regionalService.POST("/import/search-import-files", regionalImport.SearchImportFiles)
		regionalService.POST("/import/precheck-import-file", regionalImport.PrecheckImportFile)

		// for util
		regionalService.POST("/azblob/check_access", regionalUtil.CheckAzblobAccess)
		regionalService.POST("/s3/check_access", regionalUtil.CheckS3Access)
		regionalService.POST("/gcs/check_access", regionalUtil.CheckGcsAccess)
		regionalService.POST("/cluster-tables", regionalUtil.GetClusterTables)
		regionalService.POST("/cluster/execsql", regionalUtil.ExecSQLOnCluster)
		regionalService.POST("/vpc/list", regionalUtil.ListVpcs)
		regionalService.GET("/cluster/role", regionalUtil.GetClusterRole)

		regionalService.Any("/proxy/*any", gin.WrapH(proxy.Handler()))
	}
}
