// Copyright 2025 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package variable

import (
	"net/url"
	"strings"

	"github.com/pingcap/errors"
)

const (
	// OpenAIEndpointWhitelistErrMsg is returned when the configured API base host is outside the allowed set.
	OpenAIEndpointWhitelistErrMsg = "For security reasons currently only OpenAI Endpoint, Azure OpenAI Endpoint, or Alibaba Cloud Endpoint is allowed"
)

// NormalizeOpenAIEmbeddingAPIBase validates and normalizes user input for the OpenAI embedding API base.
func NormalizeOpenAIEmbeddingAPIBase(base string) (string, error) {
	trimmed := strings.TrimSpace(base)
	if trimmed == "" {
		return "", nil
	}

	u, err := url.Parse(trimmed)
	if err != nil {
		return "", errors.Annotatef(err, "invalid value for %s", TiDBExpEmbedOpenAIAPIBase)
	}
	if !u.IsAbs() || u.Host == "" {
		return "", errors.Errorf("invalid value for %s: absolute https URL is required", TiDBExpEmbedOpenAIAPIBase)
	}
	if !strings.EqualFold(u.Scheme, "https") {
		return "", errors.Errorf("invalid value for %s: only https scheme is supported", TiDBExpEmbedOpenAIAPIBase)
	}
	if u.RawQuery != "" || u.Fragment != "" {
		return "", errors.Errorf("invalid value for %s: query parameters and fragments are not allowed", TiDBExpEmbedOpenAIAPIBase)
	}

	host := strings.ToLower(u.Hostname())
	switch {
	case host == "api.openai.com":
	case strings.HasSuffix(host, ".azure.com"):
	case host == "dashscope.aliyuncs.com", host == "dashscope-intl.aliyuncs.com", host == "dashscope-us.aliyuncs.com":
	case strings.HasSuffix(host, ".maas.aliyuncs.com"):
	default:
		return "", errors.New(OpenAIEndpointWhitelistErrMsg)
	}

	normalized := "https://" + u.Host
	path := strings.TrimSuffix(u.Path, "/")
	if path != "" {
		if !strings.HasPrefix(path, "/") {
			path = "/" + path
		}
		normalized += path
	}
	normalized = strings.TrimSuffix(normalized, "/embeddings")
	return normalized, nil
}

// GetOpenAIEmbeddingBaseURL returns the configured base or the default when unset.
func GetOpenAIEmbeddingBaseURL() string {
	if base := EmbedOpenAIAPIBase.Load(); base != "" {
		return base
	}
	return DefTiDBEmbedOpenAIAPIBase
}
