package version

import (
	"fmt"
	"math"
	"slices"
)

type AgentVersionWarningType string

const (
	AgentVersionNoWarning      AgentVersionWarningType = "NO_WARNING"
	AgentVersionWarningUnknown AgentVersionWarningType = "UNKNOWN"
	AgentVersionOutdated       AgentVersionWarningType = "OUTDATED"
	AgentVersionTooNew         AgentVersionWarningType = "TOO_NEW"
)

func WarningIfOutdatedAgent(serverVersion, agentVersion Version, gitlabReleasesList []string) (AgentVersionWarningType, string) {
	// If the serverVersion is a pre-release, then we want to treat as if it was a version prior to it.
	if serverVersion.IsPre {
		prev, err := serverVersion.Previous(gitlabReleasesList)
		if err != nil {
			return AgentVersionWarningUnknown, fmt.Sprintf("Server version is a pre-release version but KAS is unable to identify the previous release version. Error: %s", err)
		}
		serverVersion = prev
	}

	// expected case where server and agent are fully compatible
	if serverVersion.Major == agentVersion.Major {
		if math.Abs(float64(serverVersion.Minor)-float64(agentVersion.Minor)) <= 4 {
			return AgentVersionNoWarning, ""
		}

		if serverVersion.Minor > agentVersion.Minor {
			return AgentVersionOutdated, "The agent for Kubernetes (agentk) is outdated by more than four minor releases and might not be compatible with the agent server for Kubernetes (KAS). You should upgrade agentk."
		} else {
			return AgentVersionTooNew, "The agent for Kubernetes (agentk) is more than four minor releases ahead of the agent server for Kubernetes (KAS). You should downgrade agentk to match KAS."
		}
	}

	// We are crossing major milestone boundaries
	serverVersionIdx := slices.Index(gitlabReleasesList, serverVersion.MajorMinor)
	if serverVersionIdx < 0 {
		// this should never happen, but its not worth enough panicking here, treat as incompatible
		return AgentVersionWarningUnknown, "The agent server for Kubernetes (KAS) version cannot be checked for compatibility. KAS and the agent for Kubernetes (agentk) might not be compatible. Make sure agentk and KAS have the same version."
	}

	agentVersionIdx := slices.Index(gitlabReleasesList, agentVersion.MajorMinor)
	if agentVersionIdx < 0 {
		// this should never happen, but its not worth enough panicking here, treat as incompatible
		return AgentVersionWarningUnknown, "The agent for Kubernetes (agentk) version cannot be checked for compatibility. Agentk and the agent server for Kubernetes (KAS) might not be compatible. Make sure agentk and KAS have the same version."
	}

	if agentVersionIdx-serverVersionIdx > 4 {
		return AgentVersionOutdated, "The agent for Kubernetes (agentk) is outdated by more than four minor releases, including a major release, and might not be compatible with the agent server for Kubernetes (KAS). You should upgrade agentk."
	}

	if serverVersionIdx-agentVersionIdx > 4 {
		return AgentVersionTooNew, "The agent for Kubernetes (agentk) is more than four minor releases ahead of the agent server for Kubernetes (KAS), including a major release. You should downgrade agentk to match KAS."
	}

	return AgentVersionNoWarning, ""
}
