package shell

import (
	"errors"
	"fmt"
	"os"
	"os/exec"
	"syscall"

	"go.wit.com/log"
)

func Exec(args []string) error {
	if len(args) == 0 {
		return errors.New("Error: Command slice is empty.")
	}

	// Start a long-running process, capture stdout and stderr
	a, b := RemoveFirstElement(args)

	process := exec.Command(a, b...)
	process.Stderr = os.Stderr
	process.Stdin = os.Stdin
	process.Stdout = os.Stdout
	process.Start()
	err := process.Wait()
	log.Log(INFO, "shell.Exec() err =", err)
	return nil
}

func ExecCheck(args []string) error {
	if len(args) == 0 {
		return errors.New("Error: Command slice is empty.")
	}

	// Start a long-running process, capture stdout and stderr
	a, b := RemoveFirstElement(args)

	process := exec.Command(a, b...)
	process.Stderr = os.Stderr
	process.Stdin = os.Stdin
	process.Stdout = os.Stdout
	err := process.Run()
	if err != nil {
		log.Info("ExecCheck() err", err)
		return err
	}
	// log.Info("ExecCheck() nil")
	return nil
}

func PathExecVerbose(path string, args []string) error {
	if len(args) == 0 {
		return errors.New("Error: Command slice is empty.")
	}

	// Start a long-running process, capture stdout and stderr
	a, b := RemoveFirstElement(args)

	process := exec.Command(a, b...)
	process.Dir = path
	process.Stderr = os.Stderr
	process.Stdin = os.Stdin
	process.Stdout = os.Stdout
	err := process.Run()
	log.Info("Exec() cmd:", args)
	if err != nil {
		log.Info("ExecCheck() err", err)
		return err
	}
	// log.Info("ExecCheck() nil")
	return nil
}

func SudoRaw(c []string) {
	args := []string{"-S"}
	args = append(args, c...)
	cmd := exec.Command("sudo", args...)

	// Assign the current process's standard input, output, and error
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin

	// Ensure the process has a terminal session
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Setsid: true, // Start a new session
	}

	err := cmd.Run()
	if err != nil {
		fmt.Println("Command execution failed:", err)
	}
}

func Sudo(c []string) error {
	args := []string{"-S"}
	// args := []string{}
	args = append(args, c...)
	cmd := exec.Command("sudo", args...)

	// Open the terminal device directly to preserve input/output control
	tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
	if err != nil {
		fmt.Println("Failed to open /dev/tty:", err)
		return err
	}
	defer tty.Close()

	// Assign the TTY explicitly
	cmd.Stdin = tty
	cmd.Stdout = tty
	cmd.Stderr = tty

	// Ensure the new process gets its own session
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Setsid: true, // Start a new session
	}

	// Run the command
	if err := cmd.Run(); err != nil {
		fmt.Println("Command execution failed:", err)
	}

	fmt.Println("\nProcess finished. TTY restored.")
	return nil
}