package clientver

import "testing"

// TestParse covers the version strings the edge actually sees: a plain and a "v"-prefixed
// triple, a `git describe --tags` suffix, build metadata, surrounding space, and the
// non-version strings (dev/empty/too-few/non-numeric) that must report ok=false so the
// gate fails open.
func TestParse(t *testing.T) {
	tests := []struct {
		name  string
		in    string
		want  Version
		wantK bool
	}{
		{"plain", "1.16.0", Version{1, 16, 0}, true},
		{"v-prefixed", "v1.16.0", Version{1, 16, 0}, true},
		{"git describe suffix", "v1.16.0-3-gabc1234", Version{1, 16, 0}, true},
		{"build metadata", "1.16.0+ci42", Version{1, 16, 0}, true},
		{"surrounding space", "  v2.0.1 ", Version{2, 0, 1}, true},
		{"extra component ignored", "v1.16.0.4", Version{1, 16, 0}, true},
		{"dev", "dev", Version{}, false},
		{"empty", "", Version{}, false},
		{"too few components", "1.16", Version{}, false},
		{"non-numeric patch", "1.16.x", Version{}, false},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			got, ok := Parse(tc.in)
			if ok != tc.wantK {
				t.Fatalf("Parse(%q) ok = %v, want %v", tc.in, ok, tc.wantK)
			}
			if ok && got != tc.want {
				t.Errorf("Parse(%q) = %+v, want %+v", tc.in, got, tc.want)
			}
		})
	}
}

// TestLess covers the ordering by MAJOR, then MINOR, then PATCH, and that an equal version
// is not Less (a client exactly at the minimum passes the gate).
func TestLess(t *testing.T) {
	tests := []struct {
		name string
		a, b Version
		want bool
	}{
		{"equal", Version{1, 16, 0}, Version{1, 16, 0}, false},
		{"major less", Version{1, 9, 9}, Version{2, 0, 0}, true},
		{"major greater", Version{2, 0, 0}, Version{1, 9, 9}, false},
		{"minor less", Version{1, 16, 5}, Version{1, 17, 0}, true},
		{"minor greater", Version{1, 17, 0}, Version{1, 16, 9}, false},
		{"patch less", Version{1, 16, 0}, Version{1, 16, 1}, true},
		{"patch greater", Version{1, 16, 2}, Version{1, 16, 1}, false},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			if got := Less(tc.a, tc.b); got != tc.want {
				t.Errorf("Less(%+v, %+v) = %v, want %v", tc.a, tc.b, got, tc.want)
			}
		})
	}
}
