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

// +build darwin linux freebsd netbsd windows openbsd

package osext

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"testing"
)

const (
	executableEnvVar = "OSTEST_OUTPUT_EXECUTABLE"

	executableEnvValueMatch  = "match"
	executableEnvValueDelete = "delete"
)

func TestPrintExecutable(t *testing.T) {
	ef, err := Executable()
	if err != nil {
		t.Fatalf("Executable failed: %v", err)
	}
	t.Log("Executable:", ef)
}
func TestPrintExecutableFolder(t *testing.T) {
	ef, err := ExecutableFolder()
	if err != nil {
		t.Fatalf("ExecutableFolder failed: %v", err)
	}
	t.Log("Executable Folder:", ef)
}
func TestExecutableFolder(t *testing.T) {
	ef, err := ExecutableFolder()
	if err != nil {
		t.Fatalf("ExecutableFolder failed: %v", err)
	}
	if ef[len(ef)-1] == filepath.Separator {
		t.Fatal("ExecutableFolder ends with a trailing slash.")
	}
}
func TestExecutableMatch(t *testing.T) {
	ep, err := Executable()
	if err != nil {
		t.Fatalf("Executable failed: %v", err)
	}

	// fullpath to be of the form "dir/prog".
	dir := filepath.Dir(filepath.Dir(ep))
	fullpath, err := filepath.Rel(dir, ep)
	if err != nil {
		t.Fatalf("filepath.Rel: %v", err)
	}
	// Make child start with a relative program path.
	// Alter argv[0] for child to verify getting real path without argv[0].
	cmd := &exec.Cmd{
		Dir:  dir,
		Path: fullpath,
		Env:  []string{fmt.Sprintf("%s=%s", executableEnvVar, executableEnvValueMatch)},
	}
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("exec(self) failed: %v", err)
	}
	outs := string(out)
	if !filepath.IsAbs(outs) {
		t.Fatalf("Child returned %q, want an absolute path", out)
	}
	if !sameFile(outs, ep) {
		t.Fatalf("Child returned %q, not the same file as %q", out, ep)
	}
}

func TestExecutableDelete(t *testing.T) {
	if runtime.GOOS != "linux" {
		t.Skip()
	}
	fpath, err := Executable()
	if err != nil {
		t.Fatalf("Executable failed: %v", err)
	}

	r, w := io.Pipe()
	stderrBuff := &bytes.Buffer{}
	stdoutBuff := &bytes.Buffer{}
	cmd := &exec.Cmd{
		Path:   fpath,
		Env:    []string{fmt.Sprintf("%s=%s", executableEnvVar, executableEnvValueDelete)},
		Stdin:  r,
		Stderr: stderrBuff,
		Stdout: stdoutBuff,
	}
	err = cmd.Start()
	if err != nil {
		t.Fatalf("exec(self) start failed: %v", err)
	}

	tempPath := fpath + "_copy"
	_ = os.Remove(tempPath)

	err = copyFile(tempPath, fpath)
	if err != nil {
		t.Fatalf("copy file failed: %v", err)
	}
	err = os.Remove(fpath)
	if err != nil {
		t.Fatalf("remove running test file failed: %v", err)
	}
	err = os.Rename(tempPath, fpath)
	if err != nil {
		t.Fatalf("rename copy to previous name failed: %v", err)
	}

	w.Write([]byte{0})
	w.Close()

	err = cmd.Wait()
	if err != nil {
		t.Fatalf("exec wait failed: %v", err)
	}

	childPath := stderrBuff.String()
	if !filepath.IsAbs(childPath) {
		t.Fatalf("Child returned %q, want an absolute path", childPath)
	}
	if !sameFile(childPath, fpath) {
		t.Fatalf("Child returned %q, not the same file as %q", childPath, fpath)
	}
}

func sameFile(fn1, fn2 string) bool {
	fi1, err := os.Stat(fn1)
	if err != nil {
		return false
	}
	fi2, err := os.Stat(fn2)
	if err != nil {
		return false
	}
	return os.SameFile(fi1, fi2)
}
func copyFile(dest, src string) error {
	df, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer df.Close()

	sf, err := os.Open(src)
	if err != nil {
		return err
	}
	defer sf.Close()

	_, err = io.Copy(df, sf)
	return err
}

func TestMain(m *testing.M) {
	env := os.Getenv(executableEnvVar)
	switch env {
	case "":
		os.Exit(m.Run())
	case executableEnvValueMatch:
		// First chdir to another path.
		dir := "/"
		if runtime.GOOS == "windows" {
			dir = filepath.VolumeName(".")
		}
		os.Chdir(dir)
		if ep, err := Executable(); err != nil {
			fmt.Fprint(os.Stderr, "ERROR: ", err)
		} else {
			fmt.Fprint(os.Stderr, ep)
		}
	case executableEnvValueDelete:
		bb := make([]byte, 1)
		var err error
		n, err := os.Stdin.Read(bb)
		if err != nil {
			fmt.Fprint(os.Stderr, "ERROR: ", err)
			os.Exit(2)
		}
		if n != 1 {
			fmt.Fprint(os.Stderr, "ERROR: n != 1, n == ", n)
			os.Exit(2)
		}
		if ep, err := Executable(); err != nil {
			fmt.Fprint(os.Stderr, "ERROR: ", err)
		} else {
			fmt.Fprint(os.Stderr, ep)
		}
	}
	os.Exit(0)
}
