package common

import (
	"fmt"
	"regexp"

	"github.com/tidbcloud/infra-provider/pkg/version"
)

var majorMinorVersionPattern = regexp.MustCompile(`^(\d+\.\d+)`)

// FormatMajorMinorVersion extracts the major.minor prefix from a full Kubernetes version string
// (e.g. "1.27.3-gke.100" -> "1.27").
func FormatMajorMinorVersion(version string) string {
	match := majorMinorVersionPattern.FindStringSubmatch(version)
	if len(match) > 1 {
		return match[1]
	}
	return ""
}

// IsVersionLower reports whether curVer is strictly lower than desiredVer.
// Versions are expected in "x.y" format (e.g. "1.29"). On parse/compare failure
// it returns false and a non-nil error so callers do not treat invalid versions as lower.
func IsVersionLower(curVer, desiredVer string) (bool, error) {
	if curVer == "" || desiredVer == "" {
		return false, fmt.Errorf("cannot compare versions: curVer=%q desiredVer=%q", curVer, desiredVer)
	}
	lower, err := version.CompareVersions(curVer, "<", desiredVer)
	if err != nil {
		return false, fmt.Errorf("compare versions %q and %q: %w", curVer, desiredVer, err)
	}
	return lower, nil
}

// ExpectToBeUpgraded reports whether desiredVer is exactly one minor version ahead of curVer
// on the same major version (control-plane upgrade step).
func ExpectToBeUpgraded(desiredVer, curVer string) bool {
	const controlPlaneMinorSkew = 1

	var desiredMajor, desiredMinor, curMajor, curMinor int
	if _, err := fmt.Sscanf(desiredVer, "%d.%d", &desiredMajor, &desiredMinor); err != nil {
		return false
	}
	if _, err := fmt.Sscanf(curVer, "%d.%d", &curMajor, &curMinor); err != nil {
		return false
	}
	return desiredMajor == curMajor && desiredMinor-curMinor == controlPlaneMinorSkew
}
