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

// +build linux darwin

package suid

import (
	"encoding/binary"
	"log"
	"os"
	"path/filepath"
	"syscall"

	"v.io/v23/verror"
)

var (
	errChownFailed        = verror.Register(pkgPath+".errChownFailed", verror.NoRetry, "{1:}{2:} os.Chown({3}, {4}, {5}) failed{:_}")
	errGetwdFailed        = verror.Register(pkgPath+".errGetwdFailed", verror.NoRetry, "{1:}{2:} os.Getwd failed{:_}")
	errStartProcessFailed = verror.Register(pkgPath+".errStartProcessFailed", verror.NoRetry, "{1:}{2:} syscall.StartProcess({3}) failed{:_}")
	errRemoveAllFailed    = verror.Register(pkgPath+".errRemoveAllFailed", verror.NoRetry, "{1:}{2:} os.RemoveAll({3}) failed{:_}")
	errFindProcessFailed  = verror.Register(pkgPath+".errFindProcessFailed", verror.NoRetry, "{1:}{2:} os.FindProcess({3}) failed{:_}")
	errKillFailed         = verror.Register(pkgPath+".errKillFailed", verror.NoRetry, "{1:}{2:} os.Process.Kill({3}) failed{:_}")
)

// Chown is only availabe on UNIX platforms so this file has a build
// restriction.
func (hw *WorkParameters) Chown() error {
	chown := func(path string, _ os.FileInfo, inerr error) error {
		if inerr != nil {
			return inerr
		}
		if hw.dryrun {
			log.Printf("[dryrun] os.Chown(%s, %d, %d)", path, hw.uid, hw.gid)
			return nil
		}
		return os.Chown(path, hw.uid, hw.gid)
	}

	chownPaths := hw.argv
	if !hw.chown {
		// Chown was invoked as part of regular suid execution, rather than directly
		// via --chown. In that case, we chown the workspace and log directory
		// TODO(rjkroege): Ensure that the device manager can read log entries.
		chownPaths = []string{hw.workspace, hw.logDir}
	}

	for _, p := range chownPaths {
		if err := filepath.Walk(p, chown); err != nil {
			return verror.New(errChownFailed, nil, p, hw.uid, hw.gid, err)
		}
	}
	return nil
}

func (hw *WorkParameters) Exec() error {
	attr := new(syscall.ProcAttr)

	dir, err := os.Getwd()
	if err != nil {
		log.Printf("error Getwd(): %v", err)
		return verror.New(errGetwdFailed, nil, err)
	}
	attr.Dir = dir
	attr.Env = hw.envv
	attr.Files = []uintptr{
		uintptr(syscall.Stdin),
		uintptr(syscall.Stdout),
		uintptr(syscall.Stderr),
	}

	attr.Sys = new(syscall.SysProcAttr)
	attr.Sys.Setsid = true
	if hw.dryrun {
		log.Printf("[dryrun] syscall.Setgid(%d)", hw.gid)
		log.Printf("[dryrun] syscall.Setuid(%d)", hw.uid)
	} else {
		attr.Sys.Credential = new(syscall.Credential)
		attr.Sys.Credential.Gid = uint32(hw.gid)
		attr.Sys.Credential.Uid = uint32(hw.uid)
	}

	// Make sure the child won't talk on the fd we use to talk back to the parent
	syscall.CloseOnExec(PipeToParentFD)

	// Start the child process
	pid, _, err := syscall.StartProcess(hw.argv0, hw.argv, attr)
	if err != nil {
		if !hw.dryrun {
			log.Printf("StartProcess failed: attr: %#v, attr.Sys: %#v, attr.Sys.Cred: %#v error: %v", attr, attr.Sys, attr.Sys.Credential, err)
		} else {
			log.Printf("StartProcess failed: %v", err)
		}
		return verror.New(errStartProcessFailed, nil, hw.argv0, err)
	}

	// Return the pid of the new child process
	pipeToParent := os.NewFile(PipeToParentFD, "pipe_to_parent_wr")
	if err = binary.Write(pipeToParent, binary.LittleEndian, int32(pid)); err != nil {
		log.Printf("Problem returning pid to parent: %v", err)
	} else {
		log.Printf("Returned pid %v to parent", pid)
	}

	os.Exit(0)
	return nil // Not reached.
}

func (hw *WorkParameters) Remove() error {
	for _, p := range hw.argv {
		if err := os.RemoveAll(p); err != nil {
			return verror.New(errRemoveAllFailed, nil, p, err)
		}
	}
	return nil
}

func (hw *WorkParameters) Kill() error {
	for _, pid := range hw.killPids {

		switch err := syscall.Kill(pid, 9); err {
		case syscall.ESRCH:
			// No such PID.
			log.Printf("process pid %d already killed", pid)
		default:
			// Something went wrong.
			return verror.New(errKillFailed, nil, pid, err)
		}

	}
	return nil
}
