package cluster

import (
	"net/http"

	"github.com/tidbcloud/clusterproxy/resolve"
	"github.com/tidbcloud/clusterproxy/route"
	"github.com/tidbcloud/clusterproxy/route/router"
	"github.com/tidbcloud/clusterproxy/util"

	"github.com/pingcap/log"
	"go.uber.org/zap"
)

const (
	serverlessDMServicePort = "8261"
)

func init() {
	router.RegisterRoute(serverlessDMRoute)
}

// DM API
var serverlessDMRoute = &route.Route{
	Name:    "tidb-serverless-dm",
	Path:    "tidb-serverless-dm",
	Version: route.V1Beta1,
	Schema: &route.Schema{
		PathRegex:       `.*`,
		RequiredHeaders: []string{},
		JSONBodyModel:   nil,
	},
	GetHandler: serverlessDMGetHandler,
}

/*
proxy request url: <baseurl>/proxy/namespace/tidb-serverless/cluster/<dm-service-name>/v1beta1/tidb-serverless-dm/...
serverlessDMGetHandler request url: serverless-dm-cluster-dm-master.tidb-serverless.svc:8261/...
*/
func serverlessDMGetHandler(c *route.Context, cl resolve.Cluster) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// namespace is tidb-serverless
		namespace := cl.Namespace
		serviceName := cl.Name
		scheme := httpsScheme
		// use mtls, reuse the client secret which signed from tidb serverless ca because dm also use the cert signed from tidb serverless ca.
		config, err := util.GetTLSConfig(c.Cli, namespace, cl.Name, serverlessClientSecretName)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if config == nil {
			scheme = httpScheme
		}
		log.Info("request serverless dm service", zap.String("namespace", namespace), zap.String("name", serviceName))
		// All request is transferred to dm service.
		proxy := route.GetKubernetesServiceProxy(
			scheme,
			namespace,
			serviceName,
			serverlessDMServicePort,
			&http.Transport{
				TLSClientConfig: config,
			})
		proxy.ServeHTTP(w, r)
	})
}
