// package cluster provides services and proxies related to the Kubernetes cluster.
package cluster

import (
	"fmt"
	"net/http"
	"strings"

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

const (
	cdcServiceFormat = "%s-ticdc-peer"
	cdcPort          = "8301"
	cdcOpenapiPrefix = "api"
)

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

var cdcRoute = &route.Route{
	Name:    "ticdc",
	Path:    "ticdc",
	Version: route.V1,
	Schema: &route.Schema{
		PathRegex:       `.*`,
		RequiredHeaders: []string{},
		JSONBodyModel:   nil,
	},
	GetHandler: cdcGetHandler,
}

/*
proxy request url: proxy/cluster/[tidb-cluster-id]/ticdc/[cdc-cluster-id]/api/v1...
cdcGetHandler request url: [cdc-cluster-id]/api/v1... or api/v1...
if url contains [cdc-cluster-id], should dispatch to right cdc service, and TrimPrefix [cdc-cluster-id]
*/
func cdcGetHandler(c *route.Context, cl resolve.Cluster) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		namespace := cl.Namespace
		var cdcServiceName string
		if !strings.HasPrefix(r.URL.Path, cdcOpenapiPrefix) {
			// mutil cdc clusters url dispatch
			paths := strings.Split(r.URL.Path, "/")
			if len(paths) <= 1 {
				http.Error(w, "wrong cdc url request", http.StatusInternalServerError)
				return
			}
			cl.Name = paths[0]
			r.URL.Path = strings.TrimPrefix(r.URL.Path, paths[0])
			r.URL.Path = strings.TrimPrefix(r.URL.Path, "/")
		}
		cdcServiceName = fmt.Sprintf(cdcServiceFormat, cl.Name)

		proxy := route.KubernetesServiceProxy("https", namespace, cdcServiceName, cdcPort)
		tlsClientSecretName := fmt.Sprintf(tlsClientSecretFormat, cl.Name)
		config, err := util.GetTLSConfig(c.Cli, namespace, cl.Name, tlsClientSecretName)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		proxy.Transport = &http.Transport{
			TLSClientConfig: config,
		}
		proxy.ServeHTTP(w, r)
	})
}
