package versioning

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestNormalize(t *testing.T) {
	t.Parallel()

	if got := Normalize(" v1.2.3 "); got != "1.2.3" {
		t.Fatalf("Normalize() = %q, want %q", got, "1.2.3")
	}
	if got := Normalize("1.2.3"); got != "1.2.3" {
		t.Fatalf("Normalize() without v prefix = %q, want %q", got, "1.2.3")
	}
}

func TestNormalizeDaemonVersionStripsAgentTeamFamily(t *testing.T) {
	t.Parallel()

	got, err := NormalizeDaemonVersion(" agentteam/v1.0.2-rc.11 ")
	require.NoError(t, err)
	require.Equal(t, "1.0.2-rc.11", got)

	got, err = NormalizeDaemonVersion("AGENTTEAM/V1.0.2")
	require.NoError(t, err)
	require.Equal(t, "1.0.2", got)
}

func TestCompareSemverHandlesPrereleaseOrdering(t *testing.T) {
	t.Parallel()

	cmp, err := CompareSemver("v1.0.2-rc.11", "1.0.2-rc.2")
	require.NoError(t, err)
	require.Greater(t, cmp, 0)

	cmp, err = CompareSemver("1.0.2", "1.0.2-rc.11")
	require.NoError(t, err)
	require.Greater(t, cmp, 0)

	cmp, err = CompareSemver("1.0.2+build.2", "1.0.2+build.1")
	require.NoError(t, err)
	require.Equal(t, 0, cmp)

	cmp, err = CompareSemver("1.0.2-alpha-beta", "1.0.2-alpha.beta")
	require.NoError(t, err)
	require.Greater(t, cmp, 0)
}

func TestCompareSemverRejectsInvalidVersions(t *testing.T) {
	t.Parallel()

	_, err := CompareSemver("1.0", "1.0.0")
	require.Error(t, err)

	_, err = CompareSemver("1.02.0", "1.0.0")
	require.Error(t, err)
}

func TestServerVersionReturnsEmptyWithoutBuildVersion(t *testing.T) {
	originalVersion := Version
	t.Cleanup(func() { Version = originalVersion })

	Version = " \t"
	if got := ServerVersion(); got != "" {
		t.Fatalf("ServerVersion() = %q, want empty string", got)
	}

	Version = "unknown"
	if got := ServerVersion(); got != "" {
		t.Fatalf("ServerVersion() = %q, want empty string", got)
	}
}

func TestServerGitCommitFallsBackToUnknown(t *testing.T) {
	originalGitCommit := GitCommit
	t.Cleanup(func() { GitCommit = originalGitCommit })

	GitCommit = " \t"
	if got := ServerGitCommit(); got != unknownGitCommit {
		t.Fatalf("ServerGitCommit() = %q, want %q", got, unknownGitCommit)
	}
}

func TestStaticProviderNormalizesVersion(t *testing.T) {
	t.Parallel()

	provider := NewStaticProvider(" v1.2.3 ")
	got, err := provider.Latest(context.Background())
	if err != nil {
		t.Fatalf("Latest() returned error: %v", err)
	}
	if got != "1.2.3" {
		t.Fatalf("Latest() = %q, want %q", got, "1.2.3")
	}
}

func TestStaticProviderRejectsNilAndEmptyVersion(t *testing.T) {
	t.Parallel()

	var nilProvider *StaticProvider
	if _, err := nilProvider.Latest(context.Background()); err == nil {
		t.Fatal("Latest() on nil provider succeeded, want error")
	}

	if _, err := NewStaticProvider(" \t").Latest(context.Background()); err == nil {
		t.Fatal("Latest() with empty version succeeded, want error")
	}
}

func TestServerBuildTimeTrimsConfiguredValue(t *testing.T) {
	previousBuildTime := BuildTime
	BuildTime = " 2026-05-24T03:04:05Z "
	t.Cleanup(func() { BuildTime = previousBuildTime })

	require.Equal(t, "2026-05-24T03:04:05Z", ServerBuildTime())
}
