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 (
	serverlessReplicationWorkerServiceName = "replication-worker-service"
	serverlessReplicationWorkerServicePort = "19000"
)

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

// TiCDC API
var serverlessReplicationWorkerRoute = &route.Route{
	Name:    "replication-worker",
	Path:    "replication-worker",
	Version: route.V1Beta1,
	Schema: &route.Schema{
		PathRegex:       `.*`,
		RequiredHeaders: []string{},
		JSONBodyModel:   nil,
	},
	GetHandler: serverlessReplicationWorkerGetHandler,
}

/*
proxy request url: <baseurl>/proxy/namespace/tidb-serverless/cluster/serverless-cluster/v1beta1/replication-worker/...
serverlessReplicationWorkerGetHandler request url: replication-worker-service.tidb-serverless.svc:19000/...
*/
func serverlessReplicationWorkerGetHandler(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 replication-worker 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 replication worker service", zap.String("namespace", namespace), zap.String("scheme", scheme))
		// All request is transferred to replication-worker service.
		proxy := route.GetKubernetesServiceProxy(
			scheme,
			namespace,
			serverlessReplicationWorkerServiceName,
			serverlessReplicationWorkerServicePort,
			&http.Transport{
				TLSClientConfig: config,
			})
		proxy.ServeHTTP(w, r)
	})
}
