// Copyright 2011 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.

//go:build (cgo || darwin) && !osusergo && unix && !android

package user

import (
	"fmt"
	"runtime"
	"strconv"
	"strings"
	"syscall"
	"unsafe"
)

func current() (*User, error) {
	return lookupUnixUid(syscall.Getuid())
}

func lookupUser(username string) (*User, error) {
	var pwd _C_struct_passwd
	var found bool
	nameC := make([]byte, len(username)+1)
	copy(nameC, username)

	err := retryWithBuffer(userBuffer, func(buf []byte) syscall.Errno {
		var errno syscall.Errno
		pwd, found, errno = _C_getpwnam_r((*_C_char)(unsafe.Pointer(&nameC[0])),
			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
		return errno
	})
	if err == syscall.ENOENT || (err == nil && !found) {
		return nil, UnknownUserError(username)
	}
	if err != nil {
		return nil, fmt.Errorf("user: lookup username %s: %v", username, err)
	}
	return buildUser(&pwd), err
}

func lookupUserId(uid string) (*User, error) {
	i, e := strconv.Atoi(uid)
	if e != nil {
		return nil, e
	}
	return lookupUnixUid(i)
}

func lookupUnixUid(uid int) (*User, error) {
	var pwd _C_struct_passwd
	var found bool

	err := retryWithBuffer(userBuffer, func(buf []byte) syscall.Errno {
		var errno syscall.Errno
		pwd, found, errno = _C_getpwuid_r(_C_uid_t(uid),
			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
		return errno
	})
	if err == syscall.ENOENT || (err == nil && !found) {
		return nil, UnknownUserIdError(uid)
	}
	if err != nil {
		return nil, fmt.Errorf("user: lookup userid %d: %v", uid, err)
	}
	return buildUser(&pwd), nil
}

func buildUser(pwd *_C_struct_passwd) *User {
	u := &User{
		Uid:      strconv.FormatUint(uint64(_C_pw_uid(pwd)), 10),
		Gid:      strconv.FormatUint(uint64(_C_pw_gid(pwd)), 10),
		Username: _C_GoString(_C_pw_name(pwd)),
		Name:     _C_GoString(_C_pw_gecos(pwd)),
		HomeDir:  _C_GoString(_C_pw_dir(pwd)),
	}
	// The pw_gecos field isn't quite standardized. Some docs
	// say: "It is expected to be a comma separated list of
	// personal data where the first item is the full name of the
	// user."
	u.Name, _, _ = strings.Cut(u.Name, ",")
	return u
}

func lookupGroup(groupname string) (*Group, error) {
	var grp _C_struct_group
	var found bool

	cname := make([]byte, len(groupname)+1)
	copy(cname, groupname)

	err := retryWithBuffer(groupBuffer, func(buf []byte) syscall.Errno {
		var errno syscall.Errno
		grp, found, errno = _C_getgrnam_r((*_C_char)(unsafe.Pointer(&cname[0])),
			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
		return errno
	})
	if err == syscall.ENOENT || (err == nil && !found) {
		return nil, UnknownGroupError(groupname)
	}
	if err != nil {
		return nil, fmt.Errorf("user: lookup groupname %s: %v", groupname, err)
	}
	return buildGroup(&grp), nil
}

func lookupGroupId(gid string) (*Group, error) {
	i, e := strconv.Atoi(gid)
	if e != nil {
		return nil, e
	}
	return lookupUnixGid(i)
}

func lookupUnixGid(gid int) (*Group, error) {
	var grp _C_struct_group
	var found bool

	err := retryWithBuffer(groupBuffer, func(buf []byte) syscall.Errno {
		var errno syscall.Errno
		grp, found, errno = _C_getgrgid_r(_C_gid_t(gid),
			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
		return syscall.Errno(errno)
	})
	if err == syscall.ENOENT || (err == nil && !found) {
		return nil, UnknownGroupIdError(strconv.Itoa(gid))
	}
	if err != nil {
		return nil, fmt.Errorf("user: lookup groupid %d: %v", gid, err)
	}
	return buildGroup(&grp), nil
}

func buildGroup(grp *_C_struct_group) *Group {
	g := &Group{
		Gid:  strconv.Itoa(int(_C_gr_gid(grp))),
		Name: _C_GoString(_C_gr_name(grp)),
	}
	return g
}

type bufferKind _C_int

var (
	userBuffer  = bufferKind(_C__SC_GETPW_R_SIZE_MAX)
	groupBuffer = bufferKind(_C__SC_GETGR_R_SIZE_MAX)
)

func (k bufferKind) initialSize() _C_size_t {
	sz := _C_sysconf(_C_int(k))
	if sz == -1 {
		// DragonFly and FreeBSD do not have _SC_GETPW_R_SIZE_MAX.
		// Additionally, not all Linux systems have it, either. For
		// example, the musl libc returns -1.
		return 1024
	}
	if !isSizeReasonable(int64(sz)) {
		// Truncate.  If this truly isn't enough, retryWithBuffer will error on the first run.
		return maxBufferSize
	}
	return _C_size_t(sz)
}

// retryWithBuffer repeatedly calls f(), increasing the size of the
// buffer each time, until f succeeds, fails with a non-ERANGE error,
// or the buffer exceeds a reasonable limit.
func retryWithBuffer(kind bufferKind, f func([]byte) syscall.Errno) error {
	buf := make([]byte, kind.initialSize())
	for {
		errno := f(buf)
		if errno == 0 {
			return nil
		} else if runtime.GOOS == "aix" && errno+1 == 0 {
			// On AIX getpwuid_r appears to return -1,
			// not ERANGE, on buffer overflow.
		} else if errno != syscall.ERANGE {
			return errno
		}
		newSize := len(buf) * 2
		if !isSizeReasonable(int64(newSize)) {
			return fmt.Errorf("internal buffer exceeds %d bytes", maxBufferSize)
		}
		buf = make([]byte, newSize)
	}
}

const maxBufferSize = 1 << 20

func isSizeReasonable(sz int64) bool {
	return sz > 0 && sz <= maxBufferSize
}

// Because we can't use cgo in tests:
func structPasswdForNegativeTest() _C_struct_passwd {
	sp := _C_struct_passwd{}
	*_C_pw_uidp(&sp) = 1<<32 - 2
	*_C_pw_gidp(&sp) = 1<<32 - 3
	return sp
}
