package cap

import (
	"errors"
	"os"
	"runtime"
	"syscall"
	"unsafe"
)

// Launcher holds a configuration for launching a child process with
// capability state different from (generally more restricted than)
// the parent.
//
// Note, go1.10 is the earliest version of the Go toolchain that can
// support this abstraction.
type Launcher struct {
	path string
	args []string
	env  []string

	callbackFn func(pa *syscall.ProcAttr, data interface{}) error

	changeUIDs bool
	uid        int

	changeGIDs bool
	gid        int
	groups     []int

	changeMode bool
	mode       Mode

	iab *IAB

	chroot string
}

// NewLauncher returns a new launcher for the specified program path
// and args with the specified environment.
func NewLauncher(path string, args []string, env []string) *Launcher {
	return &Launcher{
		path: path,
		args: args,
		env:  env,
	}
}

// Callback specifies a callback for Launch() to call before changing
// privilege. The only thing that is assumed is that the OS thread in
// use to call this callback function at launch time will be the one
// that ultimately calls fork. Any returned error value of said
// function will terminate the launch process. A nil callback (the
// default) is ignored. The specified callback fn should not call any
// "cap" package functions since this may deadlock or generate
// undefined behavior for the parent process.
func (attr *Launcher) Callback(fn func(*syscall.ProcAttr, interface{}) error) {
	attr.callbackFn = fn
}

// SetUID specifies the UID to be used by the launched command.
func (attr *Launcher) SetUID(uid int) {
	attr.changeUIDs = true
	attr.uid = uid
}

// SetGroups specifies the GID and supplementary groups for the
// launched command.
func (attr *Launcher) SetGroups(gid int, groups []int) {
	attr.changeGIDs = true
	attr.gid = gid
	attr.groups = groups
}

// SetMode specifies the libcap Mode to be used by the launched command.
func (attr *Launcher) SetMode(mode Mode) {
	attr.changeMode = true
	attr.mode = mode
}

// SetIAB specifies the AIB capability vectors to be inherited by the
// launched command. A nil value means the prevailing vectors of the
// parent will be inherited.
func (attr *Launcher) SetIAB(iab *IAB) {
	attr.iab = iab
}

// SetChroot specifies the chroot value to be used by the launched
// command. An empty value means no-change from the prevailing value.
func (attr *Launcher) SetChroot(root string) {
	attr.chroot = root
}

// lResult is used to get the result from the doomed launcher thread.
type lResult struct {
	pid int
	err error
}

// ErrLaunchFailed is returned if a launch was aborted with no more
// specific error.
var ErrLaunchFailed = errors.New("launch failed")

// ErrNoLaunch indicates the go runtime available to this binary does
// not reliably support launching. See cap.LaunchSupported.
var ErrNoLaunch = errors.New("launch not supported")

// ErrAmbiguousChroot indicates that the Launcher is being used in
// addition to a callback supplied Chroot. The former should be used
// exclusively for this.
var ErrAmbiguousChroot = errors.New("use Launcher for chroot")

// ErrAmbiguousIDs indicates that the Launcher is being used in
// addition to a callback supplied Credentials. The former should be
// used exclusively for this.
var ErrAmbiguousIDs = errors.New("use Launcher for uids and gids")

// ErrAmbiguousAmbient indicates that the Launcher is being used in
// addition to a callback supplied ambient set and the former should
// be used exclusively in a Launch call.
var ErrAmbiguousAmbient = errors.New("use Launcher for ambient caps")

// lName is the name we temporarily give to the launcher thread. Note,
// this will likely stick around in the process tree if the Go runtime
// is not cleaning up locked launcher OS threads.
var lName = []byte("cap-launcher\000")

// <uapi/linux/prctl.h>
const prSetName = 15

//go:uintptrescapes
func launch(result chan<- lResult, attr *Launcher, data interface{}, quit chan<- struct{}) {
	if quit != nil {
		defer close(quit)
	}

	pid := syscall.Getpid()
	// Wait until we are not scheduled on the parent thread.  We
	// will exit this thread once the child has launched, and
	// don't want other goroutines to use this thread afterwards.
	runtime.LockOSThread()
	tid := syscall.Gettid()
	if tid == pid {
		// Force the go runtime to find a new thread to run on.
		quit := make(chan struct{})
		go launch(result, attr, data, quit)

		// Wait for that go routine to complete.
		<-quit
		runtime.UnlockOSThread()
		return
	}

	// By never releasing the LockOSThread here, we guarantee that
	// the runtime will terminate the current OS thread once this
	// function returns.

	// Name the launcher thread - transient, but helps to debug if
	// the callbackFn or something else hangs up.
	singlesc.prctlrcall(prSetName, uintptr(unsafe.Pointer(&lName[0])), 0)

	// Provide a way to serialize the caller on the thread
	// completing.
	defer close(result)

	pa := &syscall.ProcAttr{
		Files: []uintptr{0, 1, 2},
	}
	var err error
	var needChroot bool

	if len(attr.env) != 0 {
		pa.Env = attr.env
	} else {
		pa.Env = os.Environ()
	}

	if attr.callbackFn != nil {
		if err = attr.callbackFn(pa, data); err != nil {
			goto abort
		}
	}

	if needChroot, err = validatePA(pa, attr.chroot); err != nil {
		goto abort
	}
	if attr.changeUIDs {
		if err = singlesc.setUID(attr.uid); err != nil {
			goto abort
		}
	}
	if attr.changeGIDs {
		if err = singlesc.setGroups(attr.gid, attr.groups); err != nil {
			goto abort
		}
	}
	if attr.changeMode {
		if err = singlesc.setMode(attr.mode); err != nil {
			goto abort
		}
	}
	if attr.iab != nil {
		if err = singlesc.iabSetProc(attr.iab); err != nil {
			goto abort
		}
	}

	if needChroot {
		c := GetProc()
		if err = c.SetFlag(Effective, true, SYS_CHROOT); err != nil {
			goto abort
		}
		if err = singlesc.setProc(c); err != nil {
			goto abort
		}
	}
	pid, err = syscall.ForkExec(attr.path, attr.args, pa)

abort:
	if err != nil {
		pid = -1
	}
	result <- lResult{pid: pid, err: err}
}

// Launch performs a new program launch with security state specified
// in the supplied attr settings.
func (attr *Launcher) Launch(data interface{}) (int, error) {
	if attr.path == "" || len(attr.args) == 0 {
		return -1, ErrLaunchFailed
	}
	if !LaunchSupported {
		return -1, ErrNoLaunch
	}

	scwMu.Lock()
	defer scwMu.Unlock()
	result := make(chan lResult)

	go launch(result, attr, data, nil)
	for {
		select {
		case v, ok := <-result:
			if !ok {
				return -1, ErrLaunchFailed
			}
			return v.pid, v.err
		default:
			runtime.Gosched()
		}
	}
}
