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

//go:build freebsd
// +build freebsd

package unix_test

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"testing"

	"golang.org/x/sys/unix"
)

func TestSysctlUint64(t *testing.T) {
	_, err := unix.SysctlUint64("vm.swap_total")
	if err != nil {
		t.Fatal(err)
	}
}

// FIXME: Infrastructure for launching tests in subprocesses stolen from openbsd_test.go - refactor?
// testCmd generates a proper command that, when executed, runs the test
// corresponding to the given key.

type testProc struct {
	fn      func()                    // should always exit instead of returning
	arg     func(t *testing.T) string // generate argument for test
	cleanup func(arg string) error    // for instance, delete coredumps from testing pledge
	success bool                      // whether zero-exit means success or failure
}

var (
	testProcs = map[string]testProc{}
	procName  = ""
	procArg   = ""
)

const (
	optName = "sys-unix-internal-procname"
	optArg  = "sys-unix-internal-arg"
)

func init() {
	flag.StringVar(&procName, optName, "", "internal use only")
	flag.StringVar(&procArg, optArg, "", "internal use only")

}

func testCmd(procName string, procArg string) (*exec.Cmd, error) {
	exe, err := filepath.Abs(os.Args[0])
	if err != nil {
		return nil, err
	}
	cmd := exec.Command(exe, "-"+optName+"="+procName, "-"+optArg+"="+procArg)
	cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
	return cmd, nil
}

// ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
// a testProc with a key.
func ExitsCorrectly(t *testing.T, procName string) {
	s := testProcs[procName]
	arg := "-"
	if s.arg != nil {
		arg = s.arg(t)
	}
	c, err := testCmd(procName, arg)
	defer func(arg string) {
		if err := s.cleanup(arg); err != nil {
			t.Fatalf("Failed to run cleanup for %s %s %#v", procName, err, err)
		}
	}(arg)
	if err != nil {
		t.Fatalf("Failed to construct command for %s", procName)
	}
	if (c.Run() == nil) != s.success {
		result := "succeed"
		if !s.success {
			result = "fail"
		}
		t.Fatalf("Process did not %s when it was supposed to", result)
	}
}

func TestMain(m *testing.M) {
	flag.Parse()
	if procName != "" {
		t := testProcs[procName]
		t.fn()
		os.Stderr.WriteString("test function did not exit\n")
		if t.success {
			os.Exit(1)
		} else {
			os.Exit(0)
		}
	}
	os.Exit(m.Run())
}

// end of infrastructure

const testfile = "gocapmodetest"
const testfile2 = testfile + "2"

func CapEnterTest() {
	_, err := os.OpenFile(path.Join(procArg, testfile), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		panic(fmt.Sprintf("OpenFile: %s", err))
	}

	err = unix.CapEnter()
	if err != nil {
		panic(fmt.Sprintf("CapEnter: %s", err))
	}

	_, err = os.OpenFile(path.Join(procArg, testfile2), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err == nil {
		panic("OpenFile works!")
	}
	if err.(*os.PathError).Err != unix.ECAPMODE {
		panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
	}
	os.Exit(0)
}

func makeTempDir(t *testing.T) string {
	d, err := ioutil.TempDir("", "go_openat_test")
	if err != nil {
		t.Fatalf("TempDir failed: %s", err)
	}
	return d
}

func removeTempDir(arg string) error {
	err := os.RemoveAll(arg)
	if err != nil && err.(*os.PathError).Err == unix.ENOENT {
		return nil
	}
	return err
}

func init() {
	testProcs["cap_enter"] = testProc{
		CapEnterTest,
		makeTempDir,
		removeTempDir,
		true,
	}
}

func TestCapEnter(t *testing.T) {
	if runtime.GOARCH != "amd64" {
		t.Skipf("skipping test on %s", runtime.GOARCH)
	}
	ExitsCorrectly(t, "cap_enter")
}

func OpenatTest() {
	f, err := os.Open(procArg)
	if err != nil {
		panic(err)
	}

	err = unix.CapEnter()
	if err != nil {
		panic(fmt.Sprintf("CapEnter: %s", err))
	}

	fxx, err := unix.Openat(int(f.Fd()), "xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		panic(err)
	}
	unix.Close(fxx)

	// The right to open BASE/xx is not ambient
	_, err = os.OpenFile(procArg+"/xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err == nil {
		panic("OpenFile succeeded")
	}
	if err.(*os.PathError).Err != unix.ECAPMODE {
		panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
	}

	// Can't make a new directory either
	err = os.Mkdir(procArg+"2", 0777)
	if err == nil {
		panic("MKdir succeeded")
	}
	if err.(*os.PathError).Err != unix.ECAPMODE {
		panic(fmt.Sprintf("Mkdir failed wrong: %s %#v", err, err))
	}

	// Remove all caps except read and lookup.
	r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_LOOKUP})
	if err != nil {
		panic(fmt.Sprintf("CapRightsInit failed: %s %#v", err, err))
	}
	err = unix.CapRightsLimit(f.Fd(), r)
	if err != nil {
		panic(fmt.Sprintf("CapRightsLimit failed: %s %#v", err, err))
	}

	// Check we can get the rights back again
	r, err = unix.CapRightsGet(f.Fd())
	if err != nil {
		panic(fmt.Sprintf("CapRightsGet failed: %s %#v", err, err))
	}
	b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP})
	if err != nil {
		panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
	}
	if !b {
		panic(fmt.Sprintf("Unexpected rights"))
	}
	b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP, unix.CAP_WRITE})
	if err != nil {
		panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
	}
	if b {
		panic(fmt.Sprintf("Unexpected rights (2)"))
	}

	// Can no longer create a file
	_, err = unix.Openat(int(f.Fd()), "xx2", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err == nil {
		panic("Openat succeeded")
	}
	if err != unix.ENOTCAPABLE {
		panic(fmt.Sprintf("OpenFileAt failed wrong: %s %#v", err, err))
	}

	// But can read an existing one
	_, err = unix.Openat(int(f.Fd()), "xx", os.O_RDONLY, 0666)
	if err != nil {
		panic(fmt.Sprintf("Openat failed: %s %#v", err, err))
	}

	os.Exit(0)
}

func init() {
	testProcs["openat"] = testProc{
		OpenatTest,
		makeTempDir,
		removeTempDir,
		true,
	}
}

func TestOpenat(t *testing.T) {
	if runtime.GOARCH != "amd64" {
		t.Skipf("skipping test on %s", runtime.GOARCH)
	}
	ExitsCorrectly(t, "openat")
}

func TestCapRightsSetAndClear(t *testing.T) {
	r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT})
	if err != nil {
		t.Fatalf("CapRightsInit failed: %s", err)
	}

	err = unix.CapRightsSet(r, []uint64{unix.CAP_EVENT, unix.CAP_LISTEN})
	if err != nil {
		t.Fatalf("CapRightsSet failed: %s", err)
	}

	b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT, unix.CAP_EVENT, unix.CAP_LISTEN})
	if err != nil {
		t.Fatalf("CapRightsIsSet failed: %s", err)
	}
	if !b {
		t.Fatalf("Wrong rights set")
	}

	err = unix.CapRightsClear(r, []uint64{unix.CAP_READ, unix.CAP_PDWAIT})
	if err != nil {
		t.Fatalf("CapRightsClear failed: %s", err)
	}

	b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_WRITE, unix.CAP_EVENT, unix.CAP_LISTEN})
	if err != nil {
		t.Fatalf("CapRightsIsSet failed: %s", err)
	}
	if !b {
		t.Fatalf("Wrong rights set")
	}
}

// stringsFromByteSlice converts a sequence of attributes to a []string.
// On FreeBSD, each entry consists of a single byte containing the length
// of the attribute name, followed by the attribute name.
// The name is _not_ NULL-terminated.
func stringsFromByteSlice(buf []byte) []string {
	var result []string
	i := 0
	for i < len(buf) {
		next := i + 1 + int(buf[i])
		result = append(result, string(buf[i+1:next]))
		i = next
	}
	return result
}
