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

package testenv_test

import (
	"internal/platform"
	"internal/testenv"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

func TestGoToolLocation(t *testing.T) {
	testenv.MustHaveGoBuild(t)

	var exeSuffix string
	if runtime.GOOS == "windows" {
		exeSuffix = ".exe"
	}

	// Tests are defined to run within their package source directory,
	// and this package's source directory is $GOROOT/src/internal/testenv.
	// The 'go' command is installed at $GOROOT/bin/go, so if the environment
	// is correct then testenv.GoTool() should be identical to ../../../bin/go.

	relWant := "../../../bin/go" + exeSuffix
	absWant, err := filepath.Abs(relWant)
	if err != nil {
		t.Fatal(err)
	}

	wantInfo, err := os.Stat(absWant)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("found go tool at %q (%q)", relWant, absWant)

	goTool, err := testenv.GoTool()
	if err != nil {
		t.Fatalf("testenv.GoTool(): %v", err)
	}
	t.Logf("testenv.GoTool() = %q", goTool)

	gotInfo, err := os.Stat(goTool)
	if err != nil {
		t.Fatal(err)
	}
	if !os.SameFile(wantInfo, gotInfo) {
		t.Fatalf("%q is not the same file as %q", absWant, goTool)
	}
}

func TestHasGoBuild(t *testing.T) {
	if !testenv.HasGoBuild() {
		switch runtime.GOOS {
		case "js", "wasip1":
			// No exec syscall, so these shouldn't be able to 'go build'.
			t.Logf("HasGoBuild is false on %s", runtime.GOOS)
			return
		}

		b := testenv.Builder()
		if b == "" {
			// We shouldn't make assumptions about what kind of sandbox or build
			// environment external Go users may be running in.
			t.Skipf("skipping: 'go build' unavailable")
		}

		// Since we control the Go builders, we know which ones ought
		// to be able to run 'go build'. Check that they can.
		//
		// (Note that we don't verify that any builders *can't* run 'go build'.
		// If a builder starts running 'go build' tests when it shouldn't,
		// we will presumably find out about it when those tests fail.)
		switch runtime.GOOS {
		case "ios":
			if isCorelliumBuilder(b) {
				// The corellium environment is self-hosting, so it should be able
				// to build even though real "ios" devices can't exec.
			} else {
				// The usual iOS sandbox does not allow the app to start another
				// process. If we add builders on stock iOS devices, they presumably
				// will not be able to exec, so we may as well allow that now.
				t.Logf("HasGoBuild is false on %s", b)
				return
			}
		case "android":
			if isEmulatedBuilder(b) && platform.MustLinkExternal(runtime.GOOS, runtime.GOARCH, false) {
				// As of 2023-05-02, the test environment on the emulated builders is
				// missing a C linker.
				t.Logf("HasGoBuild is false on %s", b)
				return
			}
		}

		if strings.Contains(b, "-noopt") {
			// The -noopt builder sets GO_GCFLAGS, which causes tests of 'go build' to
			// be skipped.
			t.Logf("HasGoBuild is false on %s", b)
			return
		}

		t.Fatalf("HasGoBuild unexpectedly false on %s", b)
	}

	t.Logf("HasGoBuild is true; checking consistency with other functions")

	hasExec := false
	hasExecGo := false
	t.Run("MustHaveExec", func(t *testing.T) {
		testenv.MustHaveExec(t)
		hasExec = true
	})
	t.Run("MustHaveExecPath", func(t *testing.T) {
		testenv.MustHaveExecPath(t, "go")
		hasExecGo = true
	})
	if !hasExec {
		t.Errorf(`MustHaveExec(t) skipped unexpectedly`)
	}
	if !hasExecGo {
		t.Errorf(`MustHaveExecPath(t, "go") skipped unexpectedly`)
	}

	dir := t.TempDir()
	mainGo := filepath.Join(dir, "main.go")
	if err := os.WriteFile(mainGo, []byte("package main\nfunc main() {}\n"), 0644); err != nil {
		t.Fatal(err)
	}
	cmd := testenv.Command(t, "go", "build", "-o", os.DevNull, mainGo)
	out, err := cmd.CombinedOutput()
	if err != nil {
		t.Fatalf("%v: %v\n%s", cmd, err, out)
	}
}

func TestMustHaveExec(t *testing.T) {
	hasExec := false
	t.Run("MustHaveExec", func(t *testing.T) {
		testenv.MustHaveExec(t)
		t.Logf("MustHaveExec did not skip")
		hasExec = true
	})

	switch runtime.GOOS {
	case "js", "wasip1":
		if hasExec {
			// js and wasip1 lack an “exec” syscall.
			t.Errorf("expected MustHaveExec to skip on %v", runtime.GOOS)
		}
	case "ios":
		if b := testenv.Builder(); isCorelliumBuilder(b) && !hasExec {
			// Most ios environments can't exec, but the corellium builder can.
			t.Errorf("expected MustHaveExec not to skip on %v", b)
		}
	default:
		if b := testenv.Builder(); b != "" && !hasExec {
			t.Errorf("expected MustHaveExec not to skip on %v", b)
		}
	}
}

func isCorelliumBuilder(builderName string) bool {
	// Support both the old infra's builder names and the LUCI builder names.
	// The former's names are ad-hoc so we could maintain this invariant on
	// the builder side. The latter's names are structured, and "corellium" will
	// appear as a "host" suffix after the GOOS and GOARCH, which always begin
	// with an underscore.
	return strings.HasSuffix(builderName, "-corellium") || strings.Contains(builderName, "_corellium")
}

func isEmulatedBuilder(builderName string) bool {
	// Support both the old infra's builder names and the LUCI builder names.
	// The former's names are ad-hoc so we could maintain this invariant on
	// the builder side. The latter's names are structured, and the signifier
	// of emulation "emu" will appear as a "host" suffix after the GOOS and
	// GOARCH because it modifies the run environment in such a way that it
	// the target GOOS and GOARCH may not match the host. This suffix always
	// begins with an underscore.
	return strings.HasSuffix(builderName, "-emu") || strings.Contains(builderName, "_emu")
}