package main

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

// run executes a local command, streaming stdout/stderr to os.Stdout/os.Stderr.
func run(name string, args ...string) error {
	fmt.Printf(">>> %s %s\n", name, strings.Join(args, " "))
	cmd := exec.Command(name, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

// runIn executes a local command in a specific directory.
func runIn(dir string, name string, args ...string) error {
	fmt.Printf(">>> (in %s) %s %s\n", dir, name, strings.Join(args, " "))
	cmd := exec.Command(name, args...)
	cmd.Dir = dir
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

// runOutput executes a local command and returns stdout as a string.
func runOutput(dir string, name string, args ...string) (string, error) {
	fmt.Printf(">>> %s %s\n", name, strings.Join(args, " "))
	cmd := exec.Command(name, args...)
	cmd.Dir = dir
	cmd.Stderr = os.Stderr
	var buf bytes.Buffer
	cmd.Stdout = &buf
	if err := cmd.Run(); err != nil {
		return "", err
	}
	return strings.TrimSpace(buf.String()), nil
}

// sshRun executes a command on a remote host via SSH.
func sshRun(host string, command string) error {
	fmt.Printf(">>> ssh %s %s\n", host, command)
	cmd := exec.Command("ssh", host, command)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

// sshOutput executes a command on a remote host and returns stdout.
func sshOutput(host string, command string) (string, error) {
	fmt.Printf(">>> ssh %s %s\n", host, command)
	cmd := exec.Command("ssh", host, command)
	cmd.Stderr = os.Stderr
	var buf bytes.Buffer
	cmd.Stdout = &buf
	if err := cmd.Run(); err != nil {
		return "", err
	}
	return strings.TrimSpace(buf.String()), nil
}
