// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build aix darwin dragonfly freebsd !android,linux netbsd openbsd solaris
// +build !cgo

package user

import (
	"reflect"
	"strings"
	"testing"
)

const testGroupFile = `# See the opendirectoryd(8) man page for additional 
# information about Open Directory.
##
nobody:*:-2:
nogroup:*:-1:
wheel:*:0:root
emptyid:*::root
invalidgid:*:notanumber:root
+plussign:*:20:root
-minussign:*:21:root
      
daemon:*:1:root
    indented:*:7:
# comment:*:4:found
     # comment:*:4:found
kmem:*:2:root
`

var groupTests = []struct {
	in   string
	name string
	gid  string
}{
	{testGroupFile, "nobody", "-2"},
	{testGroupFile, "kmem", "2"},
	{testGroupFile, "notinthefile", ""},
	{testGroupFile, "comment", ""},
	{testGroupFile, "plussign", ""},
	{testGroupFile, "+plussign", ""},
	{testGroupFile, "-minussign", ""},
	{testGroupFile, "minussign", ""},
	{testGroupFile, "emptyid", ""},
	{testGroupFile, "invalidgid", ""},
	{testGroupFile, "indented", "7"},
	{testGroupFile, "# comment", ""},
	{"", "emptyfile", ""},
}

func TestFindGroupName(t *testing.T) {
	for _, tt := range groupTests {
		got, err := findGroupName(tt.name, strings.NewReader(tt.in))
		if tt.gid == "" {
			if err == nil {
				t.Errorf("findGroupName(%s): got nil error, expected err", tt.name)
				continue
			}
			switch terr := err.(type) {
			case UnknownGroupError:
				if terr.Error() != "group: unknown group "+tt.name {
					t.Errorf("findGroupName(%s): got %v, want %v", tt.name, terr, tt.name)
				}
			default:
				t.Errorf("findGroupName(%s): got unexpected error %v", tt.name, terr)
			}
		} else {
			if err != nil {
				t.Fatalf("findGroupName(%s): got unexpected error %v", tt.name, err)
			}
			if got.Gid != tt.gid {
				t.Errorf("findGroupName(%s): got gid %v, want %s", tt.name, got.Gid, tt.gid)
			}
			if got.Name != tt.name {
				t.Errorf("findGroupName(%s): got name %s, want %s", tt.name, got.Name, tt.name)
			}
		}
	}
}

var groupIdTests = []struct {
	in   string
	gid  string
	name string
}{
	{testGroupFile, "-2", "nobody"},
	{testGroupFile, "2", "kmem"},
	{testGroupFile, "notinthefile", ""},
	{testGroupFile, "comment", ""},
	{testGroupFile, "7", "indented"},
	{testGroupFile, "4", ""},
	{testGroupFile, "20", ""}, // row starts with a plus
	{testGroupFile, "21", ""}, // row starts with a minus
	{"", "emptyfile", ""},
}

func TestFindGroupId(t *testing.T) {
	for _, tt := range groupIdTests {
		got, err := findGroupId(tt.gid, strings.NewReader(tt.in))
		if tt.name == "" {
			if err == nil {
				t.Errorf("findGroupId(%s): got nil error, expected err", tt.gid)
				continue
			}
			switch terr := err.(type) {
			case UnknownGroupIdError:
				if terr.Error() != "group: unknown groupid "+tt.gid {
					t.Errorf("findGroupId(%s): got %v, want %v", tt.name, terr, tt.name)
				}
			default:
				t.Errorf("findGroupId(%s): got unexpected error %v", tt.name, terr)
			}
		} else {
			if err != nil {
				t.Fatalf("findGroupId(%s): got unexpected error %v", tt.name, err)
			}
			if got.Gid != tt.gid {
				t.Errorf("findGroupId(%s): got gid %v, want %s", tt.name, got.Gid, tt.gid)
			}
			if got.Name != tt.name {
				t.Errorf("findGroupId(%s): got name %s, want %s", tt.name, got.Name, tt.name)
			}
		}
	}
}

const testUserFile = `   # Example user file
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:3:bin:/bin:/usr/sbin/nologin
     indented:x:3:3:indented:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
negative:x:-5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
allfields:x:6:12:mansplit,man2,man3,man4:/home/allfields:/usr/sbin/nologin
+plussign:x:8:10:man:/var/cache/man:/usr/sbin/nologin
-minussign:x:9:10:man:/var/cache/man:/usr/sbin/nologin

malformed:x:27:12 # more:colons:after:comment

struid:x:notanumber:12 # more:colons:after:comment

# commented:x:28:12:commented:/var/cache/man:/usr/sbin/nologin
      # commentindented:x:29:12:commentindented:/var/cache/man:/usr/sbin/nologin

struid2:x:30:badgid:struid2name:/home/struid:/usr/sbin/nologin
`

var userIdTests = []struct {
	in   string
	uid  string
	name string
}{
	{testUserFile, "-5", "negative"},
	{testUserFile, "2", "bin"},
	{testUserFile, "100", ""}, // not in the file
	{testUserFile, "8", ""},   // plus sign, glibc doesn't find it
	{testUserFile, "9", ""},   // minus sign, glibc doesn't find it
	{testUserFile, "27", ""},  // malformed
	{testUserFile, "28", ""},  // commented out
	{testUserFile, "29", ""},  // commented out, indented
	{testUserFile, "3", "indented"},
	{testUserFile, "30", ""}, // the Gid is not valid, shouldn't match
	{"", "1", ""},
}

func TestInvalidUserId(t *testing.T) {
	_, err := findUserId("notanumber", strings.NewReader(""))
	if err == nil {
		t.Fatalf("findUserId('notanumber'): got nil error")
	}
	if want := "user: invalid userid notanumber"; err.Error() != want {
		t.Errorf("findUserId('notanumber'): got %v, want %s", err, want)
	}
}

func TestLookupUserId(t *testing.T) {
	for _, tt := range userIdTests {
		got, err := findUserId(tt.uid, strings.NewReader(tt.in))
		if tt.name == "" {
			if err == nil {
				t.Errorf("findUserId(%s): got nil error, expected err", tt.uid)
				continue
			}
			switch terr := err.(type) {
			case UnknownUserIdError:
				if want := "user: unknown userid " + tt.uid; terr.Error() != want {
					t.Errorf("findUserId(%s): got %v, want %v", tt.name, terr, want)
				}
			default:
				t.Errorf("findUserId(%s): got unexpected error %v", tt.name, terr)
			}
		} else {
			if err != nil {
				t.Fatalf("findUserId(%s): got unexpected error %v", tt.name, err)
			}
			if got.Uid != tt.uid {
				t.Errorf("findUserId(%s): got uid %v, want %s", tt.name, got.Uid, tt.uid)
			}
			if got.Username != tt.name {
				t.Errorf("findUserId(%s): got name %s, want %s", tt.name, got.Username, tt.name)
			}
		}
	}
}

func TestLookupUserPopulatesAllFields(t *testing.T) {
	u, err := findUsername("allfields", strings.NewReader(testUserFile))
	if err != nil {
		t.Fatal(err)
	}
	want := &User{
		Username: "allfields",
		Uid:      "6",
		Gid:      "12",
		Name:     "mansplit",
		HomeDir:  "/home/allfields",
	}
	if !reflect.DeepEqual(u, want) {
		t.Errorf("findUsername: got %#v, want %#v", u, want)
	}
}

var userTests = []struct {
	in   string
	name string
	uid  string
}{
	{testUserFile, "negative", "-5"},
	{testUserFile, "bin", "2"},
	{testUserFile, "notinthefile", ""},
	{testUserFile, "indented", "3"},
	{testUserFile, "plussign", ""},
	{testUserFile, "+plussign", ""},
	{testUserFile, "minussign", ""},
	{testUserFile, "-minussign", ""},
	{testUserFile, "   indented", ""},
	{testUserFile, "commented", ""},
	{testUserFile, "commentindented", ""},
	{testUserFile, "malformed", ""},
	{testUserFile, "# commented", ""},
	{"", "emptyfile", ""},
}

func TestLookupUser(t *testing.T) {
	for _, tt := range userTests {
		got, err := findUsername(tt.name, strings.NewReader(tt.in))
		if tt.uid == "" {
			if err == nil {
				t.Errorf("lookupUser(%s): got nil error, expected err", tt.uid)
				continue
			}
			switch terr := err.(type) {
			case UnknownUserError:
				if want := "user: unknown user " + tt.name; terr.Error() != want {
					t.Errorf("lookupUser(%s): got %v, want %v", tt.name, terr, want)
				}
			default:
				t.Errorf("lookupUser(%s): got unexpected error %v", tt.name, terr)
			}
		} else {
			if err != nil {
				t.Fatalf("lookupUser(%s): got unexpected error %v", tt.name, err)
			}
			if got.Uid != tt.uid {
				t.Errorf("lookupUser(%s): got uid %v, want %s", tt.name, got.Uid, tt.uid)
			}
			if got.Username != tt.name {
				t.Errorf("lookupUser(%s): got name %s, want %s", tt.name, got.Username, tt.name)
			}
		}
	}
}
