package users

import "testing"

func TestParsePasswd(t *testing.T) {
	data := []byte(`root:x:0:0:root:/root:/bin/bash
# a comment

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
alice:x:1000:1000:Alice Smith:/home/alice:/bin/bash
broken:x:notanumber:5:::
short:x:2:2
`)
	got := parsePasswd(data)
	if len(got) != 3 {
		t.Fatalf("expected 3 valid users, got %d: %+v", len(got), got)
	}

	alice := got[2]
	if alice.Username != "alice" || alice.UID != 1000 || alice.GID != 1000 ||
		alice.Comment != "Alice Smith" || alice.Home != "/home/alice" ||
		alice.Shell != "/bin/bash" || alice.System {
		t.Errorf("alice parsed wrong: %+v", alice)
	}
	if !got[0].System || !got[1].System {
		t.Error("root/daemon should be flagged as system accounts")
	}
}

func TestValidateUsername(t *testing.T) {
	for _, n := range []struct {
		name  string
		value string
		valid bool
	}{
		{name: "alice", value: "alice", valid: true},
		{name: "underscore prefix", value: "_svc", valid: true},
		{name: "hyphen", value: "user-1", valid: true},
		{name: "single char", value: "a", valid: true},
		{name: "dollar suffix", value: "machine$", valid: true},
		{name: "underscore", value: "abc_def", valid: true},
		{name: "empty", value: "", valid: false},
		{name: "leading dash", value: "-rf", valid: false},
		{name: "uppercase", value: "Alice", valid: false},
		{name: "leading digit", value: "1user", valid: false},
		{name: "space", value: "a b", valid: false},
		{name: "shell metachar", value: "foo;rm", valid: false},
		{name: "colon", value: "root:x", valid: false},
		{name: "too long", value: "waytoolongusernamethatexceedsthirtytwochars", valid: false},
	} {
		t.Run(n.name, func(t *testing.T) {
			err := validateUsername(n.value)
			if n.valid && err != nil {
				t.Errorf("validateUsername(%q) = %v, want nil", n.value, err)
			}
			if !n.valid && err == nil {
				t.Errorf("validateUsername(%q) = nil, want error", n.value)
			}
		})
	}
}
