package providerbootstrap

import (
	"fmt"
	"net"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
)

var (
	baselineMu   sync.Mutex
	baselineDone = map[string]bool{}
)

func EnsureLocalBaseline(providerBaseURL, tokenURL, clientID, clientSecret, apiVersion string) error {
	if !IsLocalProviderBaseURL(providerBaseURL) {
		return nil
	}

	key := strings.TrimRight(providerBaseURL, "/") + "|" + strings.TrimRight(tokenURL, "/")

	baselineMu.Lock()
	if baselineDone[key] {
		baselineMu.Unlock()
		return nil
	}
	baselineMu.Unlock()

	scriptPath, err := BaselineScriptPath()
	if err != nil {
		return err
	}

	cmd := exec.Command("bash", scriptPath)
	cmd.Env = append(os.Environ(),
		"LOCAL_BACKEND_BASE_URL="+strings.TrimRight(providerBaseURL, "/"),
		"LOCAL_BACKEND_TOKEN_URL="+strings.TrimRight(tokenURL, "/"),
		"LOCAL_BACKEND_CLIENT_ID="+clientID,
		"LOCAL_BACKEND_CLIENT_SECRET="+clientSecret,
		"REST_API_API_VERSION="+apiVersion,
	)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("run %s: %w\n%s", filepath.Base(scriptPath), err, strings.TrimSpace(string(output)))
	}

	baselineMu.Lock()
	baselineDone[key] = true
	baselineMu.Unlock()
	return nil
}

func IsLocalProviderBaseURL(rawURL string) bool {
	parsed, err := url.Parse(strings.TrimSpace(rawURL))
	if err != nil {
		return false
	}

	host := parsed.Hostname()
	if host == "" {
		return false
	}
	if host == "localhost" {
		return true
	}

	ip := net.ParseIP(host)
	return ip != nil && ip.IsLoopback()
}

// BaselineScriptPath returns the repo-relative path to the local bootstrap script.
func BaselineScriptPath() (string, error) {
	_, filename, _, ok := runtime.Caller(0)
	if !ok {
		return "", fmt.Errorf("resolve provider bootstrap path: runtime caller unavailable")
	}
	return filepath.Clean(filepath.Join(filepath.Dir(filename), "..", "..", "rest_api", "init_local_standard_objects.sh")), nil
}
