package common

import (
	"fmt"
	"net/url"
	"os"
	"strings"
	"time"

	"github.com/go-resty/resty/v2"

	authclient "github.com/tidbcloud/aisupport/packages/sdk-go/infra/auth/client"
)

var Client *resty.Client

const (
	apiBasePath = "/api/v1/ticketmanager"
)

func SetupClient(hostURL string, timeout time.Duration) error {
	baseURL, err := url.JoinPath(hostURL, apiBasePath)
	if err != nil {
		return err
	}

	Client = resty.New().
		SetBaseURL(baseURL).
		SetTimeout(timeout).
		SetHeader("Accept", "application/json").
		OnAfterResponse(func(c *resty.Client, r *resty.Response) error {
			if !r.IsSuccess() {
				return fmt.Errorf("status: %s, body: %s", r.Status(), string(r.Body()))
			}

			return nil
		})

	// A runtime-configured Sidecar URL owns authentication. Never forward local
	// credentials to it, and never follow a redirect outside that route.
	if isSidecarURL(hostURL, os.Getenv("DS_PROXY_URL")) {
		Client.SetRedirectPolicy(resty.NoRedirectPolicy()).RemoveProxy()
		return nil
	}

	Client, err = authclient.SetupClientAuth(Client)
	if err != nil {
		return err
	}

	return nil
}

func isSidecarURL(hostURL, proxyURL string) bool {
	target, err := url.Parse(hostURL)
	if err != nil {
		return false
	}
	proxy, err := url.Parse(proxyURL)
	if err != nil || proxy.Host == "" || (proxy.Scheme != "http" && proxy.Scheme != "https") {
		return false
	}
	if target.Scheme != proxy.Scheme || target.Host != proxy.Host || target.User != nil || proxy.User != nil ||
		target.RawQuery != "" || proxy.RawQuery != "" || target.Fragment != "" || proxy.Fragment != "" {
		return false
	}
	targetPath := strings.TrimRight(target.EscapedPath(), "/")
	proxyPath := strings.TrimRight(proxy.EscapedPath(), "/")
	return targetPath == proxyPath || strings.HasPrefix(targetPath, proxyPath+"/")
}
