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

// Use an external test to avoid os/exec -> internal/testenv -> os/exec
// circular dependency.

package exec_test

import (
	"errors"
	"fmt"
	"internal/testenv"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"testing"
)

func init() {
	registerHelperCommand("exec", cmdExec)
	registerHelperCommand("lookpath", cmdLookPath)
}

func cmdLookPath(args ...string) {
	p, err := exec.LookPath(args[0])
	if err != nil {
		fmt.Fprintf(os.Stderr, "LookPath failed: %v\n", err)
		os.Exit(1)
	}
	fmt.Print(p)
}

func cmdExec(args ...string) {
	cmd := exec.Command(args[1])
	cmd.Dir = args[0]
	if errors.Is(cmd.Err, exec.ErrDot) {
		cmd.Err = nil
	}
	output, err := cmd.CombinedOutput()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Child: %s %s", err, string(output))
		os.Exit(1)
	}
	fmt.Printf("%s", string(output))
}

func installExe(t *testing.T, dest, src string) {
	fsrc, err := os.Open(src)
	if err != nil {
		t.Fatal("os.Open failed: ", err)
	}
	defer fsrc.Close()
	fdest, err := os.Create(dest)
	if err != nil {
		t.Fatal("os.Create failed: ", err)
	}
	defer fdest.Close()
	_, err = io.Copy(fdest, fsrc)
	if err != nil {
		t.Fatal("io.Copy failed: ", err)
	}
}

func installBat(t *testing.T, dest string) {
	f, err := os.Create(dest)
	if err != nil {
		t.Fatalf("failed to create batch file: %v", err)
	}
	defer f.Close()
	fmt.Fprintf(f, "@echo %s\n", dest)
}

func installProg(t *testing.T, dest, srcExe string) {
	err := os.MkdirAll(filepath.Dir(dest), 0700)
	if err != nil {
		t.Fatal("os.MkdirAll failed: ", err)
	}
	if strings.ToLower(filepath.Ext(dest)) == ".bat" {
		installBat(t, dest)
		return
	}
	installExe(t, dest, srcExe)
}

type lookPathTest struct {
	rootDir   string
	PATH      string
	PATHEXT   string
	files     []string
	searchFor string
	fails     bool // test is expected to fail
}

func (test lookPathTest) runProg(t *testing.T, env []string, cmd *exec.Cmd) (string, error) {
	cmd.Env = env
	cmd.Dir = test.rootDir
	args := append([]string(nil), cmd.Args...)
	args[0] = filepath.Base(args[0])
	cmdText := fmt.Sprintf("%q command", strings.Join(args, " "))
	out, err := cmd.CombinedOutput()
	if (err != nil) != test.fails {
		if test.fails {
			t.Fatalf("test=%+v: %s succeeded, but expected to fail", test, cmdText)
		}
		t.Fatalf("test=%+v: %s failed, but expected to succeed: %v - %v", test, cmdText, err, string(out))
	}
	if err != nil {
		return "", fmt.Errorf("test=%+v: %s failed: %v - %v", test, cmdText, err, string(out))
	}
	// normalise program output
	p := string(out)
	// trim terminating \r and \n that batch file outputs
	for len(p) > 0 && (p[len(p)-1] == '\n' || p[len(p)-1] == '\r') {
		p = p[:len(p)-1]
	}
	if !filepath.IsAbs(p) {
		return p, nil
	}
	if p[:len(test.rootDir)] != test.rootDir {
		t.Fatalf("test=%+v: %s output is wrong: %q must have %q prefix", test, cmdText, p, test.rootDir)
	}
	return p[len(test.rootDir)+1:], nil
}

func updateEnv(env []string, name, value string) []string {
	for i, e := range env {
		if strings.HasPrefix(strings.ToUpper(e), name+"=") {
			env[i] = name + "=" + value
			return env
		}
	}
	return append(env, name+"="+value)
}

func createEnv(dir, PATH, PATHEXT string) []string {
	env := os.Environ()
	env = updateEnv(env, "PATHEXT", PATHEXT)
	// Add dir in front of every directory in the PATH.
	dirs := filepath.SplitList(PATH)
	for i := range dirs {
		dirs[i] = filepath.Join(dir, dirs[i])
	}
	path := strings.Join(dirs, ";")
	env = updateEnv(env, "PATH", os.Getenv("SystemRoot")+"/System32;"+path)
	return env
}

// createFiles copies srcPath file into multiply files.
// It uses dir as prefix for all destination files.
func createFiles(t *testing.T, dir string, files []string, srcPath string) {
	for _, f := range files {
		installProg(t, filepath.Join(dir, f), srcPath)
	}
}

func (test lookPathTest) run(t *testing.T, tmpdir, printpathExe string) {
	test.rootDir = tmpdir
	createFiles(t, test.rootDir, test.files, printpathExe)
	env := createEnv(test.rootDir, test.PATH, test.PATHEXT)
	// Run "cmd.exe /c test.searchFor" with new environment and
	// work directory set. All candidates are copies of printpath.exe.
	// These will output their program paths when run.
	should, errCmd := test.runProg(t, env, exec.Command("cmd", "/c", test.searchFor))
	// Run the lookpath program with new environment and work directory set.
	have, errLP := test.runProg(t, env, helperCommand(t, "lookpath", test.searchFor))
	// Compare results.
	if errCmd == nil && errLP == nil {
		// both succeeded
		if should != have {
			t.Fatalf("test=%+v:\ncmd /c ran: %s\nlookpath found: %s", test, should, have)
		}
		return
	}
	if errCmd != nil && errLP != nil {
		// both failed -> continue
		return
	}
	if errCmd != nil {
		t.Fatal(errCmd)
	}
	if errLP != nil {
		t.Fatal(errLP)
	}
}

var lookPathTests = []lookPathTest{
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`, `p2\a`},
		searchFor: `a`,
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1.dir;p2.dir`,
		files:     []string{`p1.dir\a`, `p2.dir\a.exe`},
		searchFor: `a`,
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`},
		searchFor: `a.exe`,
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\b.exe`},
		searchFor: `b`,
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\b`, `p2\a`},
		searchFor: `a`,
		fails:     true, // TODO(brainman): do not know why this fails
	},
	// If the command name specifies a path, the shell searches
	// the specified path for an executable file matching
	// the command name. If a match is found, the external
	// command (the executable file) executes.
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`},
		searchFor: `p2\a`,
	},
	// If the command name specifies a path, the shell searches
	// the specified path for an executable file matching the command
	// name. ... If no match is found, the shell reports an error
	// and command processing completes.
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\b.exe`, `p2\a.exe`},
		searchFor: `p2\b`,
		fails:     true,
	},
	// If the command name does not specify a path, the shell
	// searches the current directory for an executable file
	// matching the command name. If a match is found, the external
	// command (the executable file) executes.
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`a`, `p1\a.exe`, `p2\a.exe`},
		searchFor: `a`,
	},
	// The shell now searches each directory specified by the
	// PATH environment variable, in the order listed, for an
	// executable file matching the command name. If a match
	// is found, the external command (the executable file) executes.
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`},
		searchFor: `a`,
	},
	// The shell now searches each directory specified by the
	// PATH environment variable, in the order listed, for an
	// executable file matching the command name. If no match
	// is found, the shell reports an error and command processing
	// completes.
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`},
		searchFor: `b`,
		fails:     true,
	},
	// If the command name includes a file extension, the shell
	// searches each directory for the exact file name specified
	// by the command name.
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`},
		searchFor: `a.exe`,
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`},
		searchFor: `a.com`,
		fails:     true, // includes extension and not exact file name match
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1`,
		files:     []string{`p1\a.exe.exe`},
		searchFor: `a.exe`,
	},
	{
		PATHEXT:   `.COM;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.exe`, `p2\a.exe`},
		searchFor: `a.exe`,
	},
	// If the command name does not include a file extension, the shell
	// adds the extensions listed in the PATHEXT environment variable,
	// one by one, and searches the directory for that file name. Note
	// that the shell tries all possible file extensions in a specific
	// directory before moving on to search the next directory
	// (if there is one).
	{
		PATHEXT:   `.COM;.EXE`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.bat`, `p2\a.exe`},
		searchFor: `a`,
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.bat`, `p2\a.exe`},
		searchFor: `a`,
	},
	{
		PATHEXT:   `.COM;.EXE;.BAT`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.bat`, `p1\a.exe`, `p2\a.bat`, `p2\a.exe`},
		searchFor: `a`,
	},
	{
		PATHEXT:   `.COM`,
		PATH:      `p1;p2`,
		files:     []string{`p1\a.bat`, `p2\a.exe`},
		searchFor: `a`,
		fails:     true, // tried all extensions in PATHEXT, but none matches
	},
}

func TestLookPathWindows(t *testing.T) {
	tmp := t.TempDir()
	printpathExe := buildPrintPathExe(t, tmp)

	// Run all tests.
	for i, test := range lookPathTests {
		t.Run(fmt.Sprint(i), func(t *testing.T) {
			dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
			err := os.Mkdir(dir, 0700)
			if err != nil {
				t.Fatal("Mkdir failed: ", err)
			}
			test.run(t, dir, printpathExe)
		})
	}
}

type commandTest struct {
	PATH  string
	files []string
	dir   string
	arg0  string
	want  string
	fails bool // test is expected to fail
}

func (test commandTest) isSuccess(rootDir, output string, err error) error {
	if err != nil {
		return fmt.Errorf("test=%+v: exec: %v %v", test, err, output)
	}
	path := output
	if path[:len(rootDir)] != rootDir {
		return fmt.Errorf("test=%+v: %q must have %q prefix", test, path, rootDir)
	}
	path = path[len(rootDir)+1:]
	if path != test.want {
		return fmt.Errorf("test=%+v: want %q, got %q", test, test.want, path)
	}
	return nil
}

func (test commandTest) runOne(t *testing.T, rootDir string, env []string, dir, arg0 string) {
	cmd := helperCommand(t, "exec", dir, arg0)
	cmd.Dir = rootDir
	cmd.Env = env
	output, err := cmd.CombinedOutput()
	err = test.isSuccess(rootDir, string(output), err)
	if (err != nil) != test.fails {
		if test.fails {
			t.Errorf("test=%+v: succeeded, but expected to fail", test)
		} else {
			t.Error(err)
		}
	}
}

func (test commandTest) run(t *testing.T, rootDir, printpathExe string) {
	createFiles(t, rootDir, test.files, printpathExe)
	PATHEXT := `.COM;.EXE;.BAT`
	env := createEnv(rootDir, test.PATH, PATHEXT)
	test.runOne(t, rootDir, env, test.dir, test.arg0)
}

var commandTests = []commandTest{
	// testing commands with no slash, like `a.exe`
	{
		// should find a.exe in current directory
		files: []string{`a.exe`},
		arg0:  `a.exe`,
		want:  `a.exe`,
	},
	{
		// like above, but add PATH in attempt to break the test
		PATH:  `p2;p`,
		files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
		arg0:  `a.exe`,
		want:  `a.exe`,
	},
	{
		// like above, but use "a" instead of "a.exe" for command
		PATH:  `p2;p`,
		files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
		arg0:  `a`,
		want:  `a.exe`,
	},
	// testing commands with slash, like `.\a.exe`
	{
		// should find p\a.exe
		files: []string{`p\a.exe`},
		arg0:  `p\a.exe`,
		want:  `p\a.exe`,
	},
	{
		// like above, but adding `.` in front of executable should still be OK
		files: []string{`p\a.exe`},
		arg0:  `.\p\a.exe`,
		want:  `p\a.exe`,
	},
	{
		// like above, but with PATH added in attempt to break it
		PATH:  `p2`,
		files: []string{`p\a.exe`, `p2\a.exe`},
		arg0:  `p\a.exe`,
		want:  `p\a.exe`,
	},
	{
		// like above, but make sure .exe is tried even for commands with slash
		PATH:  `p2`,
		files: []string{`p\a.exe`, `p2\a.exe`},
		arg0:  `p\a`,
		want:  `p\a.exe`,
	},
	// tests commands, like `a.exe`, with c.Dir set
	{
		// should not find a.exe in p, because LookPath(`a.exe`) will fail
		files: []string{`p\a.exe`},
		dir:   `p`,
		arg0:  `a.exe`,
		want:  `p\a.exe`,
		fails: true,
	},
	{
		// LookPath(`a.exe`) will find `.\a.exe`, but prefixing that with
		// dir `p\a.exe` will refer to a non-existent file
		files: []string{`a.exe`, `p\not_important_file`},
		dir:   `p`,
		arg0:  `a.exe`,
		want:  `a.exe`,
		fails: true,
	},
	{
		// like above, but making test succeed by installing file
		// in referred destination (so LookPath(`a.exe`) will still
		// find `.\a.exe`, but we successfully execute `p\a.exe`)
		files: []string{`a.exe`, `p\a.exe`},
		dir:   `p`,
		arg0:  `a.exe`,
		want:  `p\a.exe`,
	},
	{
		// like above, but add PATH in attempt to break the test
		PATH:  `p2;p`,
		files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
		dir:   `p`,
		arg0:  `a.exe`,
		want:  `p\a.exe`,
	},
	{
		// like above, but use "a" instead of "a.exe" for command
		PATH:  `p2;p`,
		files: []string{`a.exe`, `p\a.exe`, `p2\a.exe`},
		dir:   `p`,
		arg0:  `a`,
		want:  `p\a.exe`,
	},
	{
		// finds `a.exe` in the PATH regardless of dir set
		// because LookPath returns full path in that case
		PATH:  `p2;p`,
		files: []string{`p\a.exe`, `p2\a.exe`},
		dir:   `p`,
		arg0:  `a.exe`,
		want:  `p2\a.exe`,
	},
	// tests commands, like `.\a.exe`, with c.Dir set
	{
		// should use dir when command is path, like ".\a.exe"
		files: []string{`p\a.exe`},
		dir:   `p`,
		arg0:  `.\a.exe`,
		want:  `p\a.exe`,
	},
	{
		// like above, but with PATH added in attempt to break it
		PATH:  `p2`,
		files: []string{`p\a.exe`, `p2\a.exe`},
		dir:   `p`,
		arg0:  `.\a.exe`,
		want:  `p\a.exe`,
	},
	{
		// like above, but make sure .exe is tried even for commands with slash
		PATH:  `p2`,
		files: []string{`p\a.exe`, `p2\a.exe`},
		dir:   `p`,
		arg0:  `.\a`,
		want:  `p\a.exe`,
	},
}

func TestCommand(t *testing.T) {
	tmp := t.TempDir()
	printpathExe := buildPrintPathExe(t, tmp)

	// Run all tests.
	for i, test := range commandTests {
		dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
		err := os.Mkdir(dir, 0700)
		if err != nil {
			t.Fatal("Mkdir failed: ", err)
		}
		test.run(t, dir, printpathExe)
	}
}

// buildPrintPathExe creates a Go program that prints its own path.
// dir is a temp directory where executable will be created.
// The function returns full path to the created program.
func buildPrintPathExe(t *testing.T, dir string) string {
	const name = "printpath"
	srcname := name + ".go"
	err := os.WriteFile(filepath.Join(dir, srcname), []byte(printpathSrc), 0644)
	if err != nil {
		t.Fatalf("failed to create source: %v", err)
	}
	if err != nil {
		t.Fatalf("failed to execute template: %v", err)
	}
	outname := name + ".exe"
	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", outname, srcname)
	cmd.Dir = dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("failed to build executable: %v - %v", err, string(out))
	}
	return filepath.Join(dir, outname)
}

const printpathSrc = `
package main

import (
	"os"
	"syscall"
	"unicode/utf16"
	"unsafe"
)

func getMyName() (string, error) {
	var sysproc = syscall.MustLoadDLL("kernel32.dll").MustFindProc("GetModuleFileNameW")
	b := make([]uint16, syscall.MAX_PATH)
	r, _, err := sysproc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)))
	n := uint32(r)
	if n == 0 {
		return "", err
	}
	return string(utf16.Decode(b[0:n])), nil
}

func main() {
	path, err := getMyName()
	if err != nil {
		os.Stderr.Write([]byte("getMyName failed: " + err.Error() + "\n"))
		os.Exit(1)
	}
	os.Stdout.Write([]byte(path))
}
`
