package model

import (
	"strings"
	"testing"
)

func TestValidateVMName(t *testing.T) {
	cases := []struct {
		name       string
		input      string
		wantOK     bool
		wantErrSub string
	}{
		// Happy path.
		{"simple", "mybox", true, ""},
		{"with-hyphen", "my-box", true, ""},
		{"digits", "box-123", true, ""},
		{"digits-only", "1234", true, ""},
		{"single-char", "a", true, ""},
		{"max length", strings.Repeat("a", MaxVMNameLen), true, ""},
		{"namegen style", "ace-fox", true, ""},

		// Empty / length.
		{"empty", "", false, "required"},
		{"over max length", strings.Repeat("a", MaxVMNameLen+1), false, "max is"},

		// Hyphen position.
		{"leading hyphen", "-box", false, "cannot start or end with '-'"},
		{"trailing hyphen", "box-", false, "cannot start or end with '-'"},
		{"lone hyphen", "-", false, "cannot start or end with '-'"},

		// Character class.
		{"uppercase", "MyBox", false, "invalid character"},
		{"space", "my box", false, "invalid character"},
		{"newline", "my\nbox", false, "invalid character"},
		{"tab", "my\tbox", false, "invalid character"},
		{"dot", "my.box", false, "invalid character"},
		{"dot-vm suffix", "box.vm", false, "invalid character"},
		{"slash", "my/box", false, "invalid character"},
		{"underscore", "my_box", false, "invalid character"},
		{"at sign", "user@box", false, "invalid character"},
		{"colon (kernel cmdline separator)", "my:box", false, "invalid character"},
		{"equals (kernel cmdline)", "a=b", false, "invalid character"},
		{"quote", "my\"box", false, "invalid character"},
		{"unicode letter", "box-α", false, "invalid character"},
		{"leading space", " box", false, "invalid character"},
		{"trailing space", "box ", false, "invalid character"},
		{"control char NUL", "my\x00box", false, "invalid character"},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			err := ValidateVMName(tc.input)
			if tc.wantOK {
				if err != nil {
					t.Fatalf("ValidateVMName(%q) = %v, want nil", tc.input, err)
				}
				return
			}
			if err == nil {
				t.Fatalf("ValidateVMName(%q) = nil, want error containing %q", tc.input, tc.wantErrSub)
			}
			if !strings.Contains(err.Error(), tc.wantErrSub) {
				t.Fatalf("ValidateVMName(%q) = %v, want error containing %q", tc.input, err, tc.wantErrSub)
			}
		})
	}
}
