// Package cluster provides services and proxies related to the Kubernetes cluster.
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 (
	serverlessBrServiceName    = "tikv-api-service"
	serverlessBrServicePort    = "19500"
	serverlessClientSecretName = "clusterproxy-client-secret"
)

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

var serverlessRoute = &route.Route{
	Name:    "serverless",
	Path:    "serverless",
	Version: route.V1Beta1,
	Schema: &route.Schema{
		PathRegex:       `.*`,
		RequiredHeaders: []string{},
		JSONBodyModel:   nil,
	},
	GetHandler: serverlessGetHandler,
}

/*
proxy request url: proxy/cluster/[tidb-cluster-id]/v1beta1/serverless/...
serverlessGetHandler request url: tikv-api-service.tidb-serverless.svc:19500/...
*/
func serverlessGetHandler(c *route.Context, cl resolve.Cluster) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		namespace := cl.Namespace
		scheme := httpsScheme
		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 tikv service", zap.String("namespace", namespace), zap.String("scheme", scheme))
		// All request is transferred to tikv-api service.
		proxy := route.GetKubernetesServiceProxy(scheme, namespace, serverlessBrServiceName, serverlessBrServicePort, &http.Transport{
			TLSClientConfig: config,
		})
		proxy.ServeHTTP(w, r)
	})
}
