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

package impl

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"os/user"
	"strconv"

	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/x/ref/services/device/internal/errors"
)

type suidHelperState struct {
	dmUser     string // user that the device manager is running as
	helperPath string // path to the suidhelper binary
}

var suidHelper *suidHelperState

func InitSuidHelper(ctx *context.T, helperPath string) {
	if suidHelper != nil {
		return
	}
	if helperPath == "" {
		ctx.Panicf("suidhelper path needs to be specified")
	}

	var userName string
	if user, _ := user.Current(); user != nil && len(user.Username) > 0 {
		userName = user.Username
	} else {
		userName = "anonymous"
	}
	suidHelper = &suidHelperState{
		dmUser:     userName,
		helperPath: helperPath,
	}
}

func (s suidHelperState) getCurrentUser() string {
	return s.dmUser
}

// terminatePid sends a SIGKILL to the target pid
func (s suidHelperState) terminatePid(ctx *context.T, pid int, stdout, stderr io.Writer) error {
	if err := s.internalModalOp(ctx, stdout, stderr, "--kill", strconv.Itoa(pid)); err != nil {
		return fmt.Errorf("devicemanager's invocation of suidhelper to kill pid %v failed: %v", pid, err)
	}
	return nil
}

func DeleteFileTree(ctx *context.T, dirOrFile string, stdout, stderr io.Writer) error {
	return suidHelper.deleteFileTree(ctx, dirOrFile, stdout, stderr)
}

// deleteFileTree deletes a file or directory
func (s suidHelperState) deleteFileTree(ctx *context.T, dirOrFile string, stdout, stderr io.Writer) error {
	if err := s.internalModalOp(ctx, stdout, stderr, "--rm", dirOrFile); err != nil {
		return fmt.Errorf("devicemanager's invocation of suidhelper delete %v failed: %v", dirOrFile, err)
	}
	return nil
}

// chown files or directories
func (s suidHelperState) chownTree(ctx *context.T, username string, dirOrFile string, stdout, stderr io.Writer) error {
	args := []string{"--chown", "--username", username, dirOrFile}

	if err := s.internalModalOp(ctx, stdout, stderr, args...); err != nil {
		return fmt.Errorf("devicemanager's invocation of suidhelper chown %v failed: %v", dirOrFile, err)
	}
	return nil
}

type suidAppCmdArgs struct {
	// args to helper
	targetUser, progname, workspace, logdir, binpath, sockPath string
	// fields in exec.Cmd
	env            []string
	stdout, stderr io.Writer
	dir            string
	// arguments passed to app
	appArgs []string
}

// getAppCmd produces an exec.Cmd that can be used to start an app
func (s suidHelperState) getAppCmd(ctx *context.T, a *suidAppCmdArgs) (*exec.Cmd, error) {
	if a.targetUser == "" || a.progname == "" || a.binpath == "" || a.workspace == "" || a.logdir == "" {
		return nil, fmt.Errorf("Invalid args passed to getAppCmd: %+v", a)
	}

	cmd := exec.Command(s.helperPath)

	switch yes, err := s.suidhelperEnabled(ctx, a.targetUser); {
	case err != nil:
		return nil, err
	case yes:
		cmd.Args = append(cmd.Args, "--username", a.targetUser)
	case !yes:
		cmd.Args = append(cmd.Args, "--username", a.targetUser, "--dryrun")
	}

	cmd.Args = append(cmd.Args, "--progname", a.progname)
	cmd.Args = append(cmd.Args, "--workspace", a.workspace)
	cmd.Args = append(cmd.Args, "--logdir", a.logdir)
	if a.sockPath != "" {
		cmd.Args = append(cmd.Args, "--agentsock", a.sockPath)
	}

	cmd.Args = append(cmd.Args, "--run", a.binpath)
	cmd.Args = append(cmd.Args, "--")

	cmd.Args = append(cmd.Args, a.appArgs...)

	cmd.Env = a.env
	cmd.Stdout = a.stdout
	cmd.Stderr = a.stderr
	cmd.Dir = a.dir

	return cmd, nil
}

// internalModalOp is a convenience routine containing the common part of all
// modal operations. Only other routines implementing specific suidhelper operations
// (like terminatePid and deleteFileTree) should call this directly.
func (s suidHelperState) internalModalOp(ctx *context.T, stdout, stderr io.Writer, arg ...string) error {
	cmd := exec.Command(s.helperPath)
	cmd.Args = append(cmd.Args, arg...)
	if stderr != nil {
		cmd.Stderr = stderr
	}
	if stdout != nil {
		cmd.Stdout = stdout
	}

	if err := cmd.Run(); err != nil {
		ctx.Errorf("failed calling helper with args (%v):%v", arg, err)
		return err
	}
	return nil
}

// IsSetuid is defined like this so we can override its
// implementation for tests.
var IsSetuid = func(ctx *context.T, fileStat os.FileInfo) bool {
	ctx.VI(2).Infof("running the original isSetuid")
	return fileStat.Mode()&os.ModeSetuid == os.ModeSetuid
}

// suidhelperEnabled determines if the suidhelper must exist and be
// setuid to run an application as system user targetUser. If false, the
// setuidhelper must be invoked with the --dryrun flag to skip making
// system calls that will fail or provide apps with a trivial
// priviledge escalation.
func (s suidHelperState) suidhelperEnabled(ctx *context.T, targetUser string) (bool, error) {
	helperStat, err := os.Stat(s.helperPath)
	if err != nil {
		return false, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Stat(%v) failed: %v. helper is required.", s.helperPath, err))
	}
	haveHelper := IsSetuid(ctx, helperStat)

	switch {
	case haveHelper && s.dmUser != targetUser:
		return true, nil
	case haveHelper && s.dmUser == targetUser:
		return false, verror.New(verror.ErrNoAccess, nil, fmt.Sprintf("suidhelperEnabled failed: %q == %q", s.dmUser, targetUser))
	default:
		return false, nil
	}
}

// usernameForPrincipal returns the system name that the
// devicemanager will use to invoke apps.
// TODO(rjkroege): This code assumes a desktop target and will need
// to be reconsidered for embedded contexts.
func (s suidHelperState) usernameForPrincipal(ctx *context.T, call security.Call, uat BlessingSystemAssociationStore) string {
	identityNames, _ := security.RemoteBlessingNames(ctx, call)
	systemName, present := uat.SystemAccountForBlessings(identityNames)
	if present {
		return systemName
	} else {
		return s.dmUser
	}
}
