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 (
	serverlessPDServiceName = "serverless-cluster-pd"
	serverlessPDServicePort = "2379"
)

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

// PD API
var serverlessPDRoute = &route.Route{
	Name:    "tidb-serverless-pd",
	Path:    "tidb-serverless-pd",
	Version: route.V1Beta1,
	Schema: &route.Schema{
		PathRegex:       `.*`,
		RequiredHeaders: []string{},
		JSONBodyModel:   nil,
	},
	GetHandler: serverlessPDGetHandler,
}

/*
proxy request url: <baseurl>/proxy/namespace/tidb-serverless/cluster/serverless-cluster/v1beta1/tidb-serverless-pd/...
serverlessPDGetHandler request url: serverless-cluster-pd.tidb-serverless.svc:2379/...
*/
func serverlessPDGetHandler(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
		scheme := httpsScheme
		// use mtls, reuse the client secret which signed from tidb serverless ca because pd 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 pd service", zap.String("namespace", namespace), zap.String("scheme", scheme))
		// All request is transferred to pd service.
		proxy := route.GetKubernetesServiceProxy(
			scheme,
			namespace,
			serverlessPDServiceName,
			serverlessPDServicePort,
			&http.Transport{
				TLSClientConfig: config,
			})
		proxy.ServeHTTP(w, r)
	})
}
