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

// Test the device manager and related services and tools.
//
// By default, this script tests the device manager in a fashion amenable
// to automatic testing: the --single_user is passed to the device
// manager so that all device manager components run as the same user and
// no user input (such as an agent pass phrase) is needed.
//
// This script can exercise the device manager in two different modes. It
// can be executed like so:
//
// v23 go test -v . --v23.tests
//
// This will exercise the device manager's single user mode where all
// processes run as the same invoking user.
//
// Alternatively, the device manager can be executed in multiple account
// mode by providing the --deviceuser <deviceuser> and --appuser
// <appuser> flags. In this case, the device manager will run as user
// <devicemgr> and the test will run applications as user <appuser>. If
// executed in this fashion, root permissions will be required to install
// and it may require configuring an agent passphrase. For example:
//
//   v23 go test -v . --v23.tests --deviceuser devicemanager --appuser  vana
//
// NB: the accounts provided as arguments to this test must already exist.
// Also, the --v23.tests.shell-on-fail flag is useful to enable debugging
// output.

package device_test

//go:generate v23 test generate .

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"math/rand"
	"os"
	"os/user"
	"path/filepath"
	"regexp"
	"strings"
	"time"

	"v.io/x/ref/envvar"
	_ "v.io/x/ref/profiles"
	"v.io/x/ref/test/v23tests"
)

var (
	appUserFlag    string
	deviceUserFlag string
	hostname       string
	errTimeout     = errors.New("timeout")
)

func init() {
	flag.StringVar(&appUserFlag, "appuser", "", "launch apps as the specified user")
	flag.StringVar(&deviceUserFlag, "deviceuser", "", "run the device manager as the specified user")
	name, err := os.Hostname()
	if err != nil {
		panic(fmt.Sprintf("Hostname() failed: %v", err))
	}
	hostname = name
}

func V23TestDeviceManager(i *v23tests.T) {
	defer fmt.Fprintf(os.Stderr, "--------------- SHUTDOWN ---------------\n")
	userFlag := "--single_user"
	withSuid := false
	tempDir := ""
	if len(deviceUserFlag) > 0 && len(appUserFlag) > 0 {
		withSuid = true
		i.Logf("device user %s, app user %s", deviceUserFlag, appUserFlag)
		// When running --with_suid, TMPDIR must grant the
		// invoking user rwx permissions and world x permissions for
		// all parent directories back to /. Otherwise, the
		// with_suid user will not be able to use absolute paths.
		// On Darwin, TMPDIR defaults to a directory hieararchy
		// in /var that is 0700. This is unworkable so force
		// TMPDIR to /tmp in this case.
		tempDir = "/tmp"
	} else if len(deviceUserFlag) > 0 || len(appUserFlag) > 0 {
		i.Fatalf("Running in multiuser mode requires --appuser and --deviceuser")
	} else {
		u, err := user.Current()
		if err != nil {
			i.Fatalf("couldn't get the current user: %v", err)
		}
		appUserFlag = u.Username
	}

	var (
		workDir       = i.NewTempDir(tempDir)
		binStagingDir = mkSubdir(i, workDir, "bin")
		dmInstallDir  = filepath.Join(workDir, "dm")

		// All vanadium command-line utitilities will be run by a
		// principal that has "root/alice" as its blessing.
		// (Where "root" comes from i.Principal().BlessingStore().Default()).
		// Create those credentials and options to use to setup the
		// binaries with them.
		aliceCreds, _ = i.Shell().NewChildCredentials("alice")
		aliceOpts     = i.Shell().DefaultStartOpts().ExternalCommand().WithCustomCredentials(aliceCreds)

		// Build all the command-line tools and set them up to run as alice.
		// applicationd/binaryd servers will be run by alice too.
		namespaceBin    = i.BuildV23Pkg("v.io/x/ref/cmd/namespace").WithStartOpts(aliceOpts)
		debugBin        = i.BuildV23Pkg("v.io/x/ref/services/debug/debug").WithStartOpts(aliceOpts)
		deviceBin       = i.BuildV23Pkg("v.io/x/ref/services/device/device").WithStartOpts(aliceOpts)
		binaryBin       = i.BuildV23Pkg("v.io/x/ref/services/binary/binary").WithStartOpts(aliceOpts)
		applicationBin  = i.BuildV23Pkg("v.io/x/ref/services/application/application").WithStartOpts(aliceOpts)
		binarydBin      = i.BuildV23Pkg("v.io/x/ref/services/binary/binaryd").WithStartOpts(aliceOpts)
		applicationdBin = i.BuildV23Pkg("v.io/x/ref/services/application/applicationd").WithStartOpts(aliceOpts)

		// The devicex script is not provided with any credentials, it
		// will generate its own.  This means that on "devicex start"
		// the device will have no useful credentials and until "device
		// claim" is invoked (as alice), it will just sit around
		// waiting to be claimed.
		//
		// Other binaries, like applicationd and binaryd will be run by alice.
		deviceScript = i.BinaryFromPath("./devicex").WithEnv("V23_DEVICE_DIR=" + dmInstallDir)

		mtName = "devices/" + hostname // Name under which the device manager will publish itself.
	)

	if withSuid {
		// In multiuser mode, deviceUserFlag needs execute access to
		// tempDir.
		if err := os.Chmod(workDir, 0711); err != nil {
			i.Fatalf("os.Chmod() failed: %v", err)
		}
	}

	v23tests.RunRootMT(i, "--v23.tcp.address=127.0.0.1:0")
	buildAndCopyBinaries(
		i,
		binStagingDir,
		"v.io/x/ref/services/device/deviced",
		"v.io/x/ref/services/agent/agentd",
		"v.io/x/ref/services/device/suidhelper",
		"v.io/x/ref/services/device/inithelper")

	appDName := "applicationd"
	devicedAppName := filepath.Join(appDName, "deviced", "test")

	deviceScriptArguments := []string{
		"install",
		binStagingDir,
	}

	if withSuid {
		deviceScriptArguments = append(deviceScriptArguments, "--devuser="+deviceUserFlag)
	} else {
		deviceScriptArguments = append(deviceScriptArguments, userFlag)
	}

	deviceScriptArguments = append(deviceScriptArguments, []string{
		"--origin=" + devicedAppName,
		"--",
		"--v23.tcp.address=127.0.0.1:0",
		"--neighborhood-name=" + fmt.Sprintf("%s-%d-%d", hostname, os.Getpid(), rand.Int()),
	}...)

	deviceScript.Start(deviceScriptArguments...).WaitOrDie(os.Stdout, os.Stderr)
	deviceScript.Start("start").WaitOrDie(os.Stdout, os.Stderr)

	resolve := func(name string) string {
		resolver := func() (interface{}, error) {
			// Use Start, rather than Run, since it's ok for 'namespace resolve'
			// to fail with 'name doesn't exist'
			inv := namespaceBin.Start("resolve", name)
			// Cleanup after ourselves to avoid leaving a ton of invocations
			// lying around which obscure logging output.
			defer inv.Wait(nil, os.Stderr)
			if r := strings.TrimRight(inv.Output(), "\n"); len(r) > 0 {
				return r, nil
			}
			return nil, nil
		}
		return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string)
	}
	mtEP := resolve(mtName)

	// Verify that device manager's mounttable is published under the expected
	// name (hostname).
	if got := namespaceBin.Run("glob", mtName); len(got) == 0 {
		i.Fatalf("glob failed for %q", mtName)
	}

	// Claim the device as "root/alice/myworkstation".
	deviceBin.Start("claim", mtName+"/devmgr/device", "myworkstation")

	resolveChange := func(name, old string) string {
		resolver := func() (interface{}, error) {
			inv := namespaceBin.Start("resolve", name)
			defer inv.Wait(nil, os.Stderr)
			if r := strings.TrimRight(inv.Output(), "\n"); len(r) > 0 && r != old {
				return r, nil
			}
			return nil, nil
		}
		return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string)
	}

	// Wait for the device manager to update its mount table entry.
	mtEP = resolveChange(mtName, mtEP)

	if withSuid {
		deviceBin.Start("associate", "add", mtName+"/devmgr/device", appUserFlag, "root/alice")

		aai := deviceBin.Start("associate", "list", mtName+"/devmgr/device")
		if got, expected := strings.Trim(aai.Output(), "\n "), "root/alice "+appUserFlag; got != expected {
			i.Fatalf("association test, got %v, expected %v", got, expected)
		}
	}

	// Verify the device's default blessing is as expected.
	inv := debugBin.Start("stats", "read", mtName+"/devmgr/__debug/stats/security/principal/*/blessingstore")
	inv.ExpectSetEventuallyRE(".*Default Blessings[ ]+root/alice/myworkstation$")

	// Get the device's profile, which should be set to non-empty string
	inv = deviceBin.Start("describe", mtName+"/devmgr/device")

	parts := inv.ExpectRE(`{Profiles:map\[(.*):{}\]}`, 1)
	expectOneMatch := func(parts [][]string) string {
		if len(parts) != 1 || len(parts[0]) != 2 {
			loc := v23tests.Caller(1)
			i.Fatalf("%s: failed to match profile: %#v", loc, parts)
		}
		return parts[0][1]
	}
	deviceProfile := expectOneMatch(parts)
	if len(deviceProfile) == 0 {
		i.Fatalf("failed to get profile")
	}

	// Start a binaryd server that will serve the binary for the test
	// application to be installed on the device.
	binarydName := "binaryd"
	binarydBin.Start(
		"--name="+binarydName,
		"--root-dir="+filepath.Join(workDir, "binstore"),
		"--v23.tcp.address=127.0.0.1:0",
		"--http=127.0.0.1:0")
	sampleAppBinName := binarydName + "/testapp"
	binaryBin.Run("upload", sampleAppBinName, binarydBin.Path())
	if got := namespaceBin.Run("glob", sampleAppBinName); len(got) == 0 {
		i.Fatalf("glob failed for %q", sampleAppBinName)
	}

	// Start an applicationd server that will serve the application
	// envelope for the test application to be installed on the device.
	applicationdBin.Start(
		"--name="+appDName,
		"--store="+mkSubdir(i, workDir, "appstore"),
		"--v23.tcp.address=127.0.0.1:0",
	)
	sampleAppName := appDName + "/testapp/v0"
	appPubName := "testbinaryd"
	appEnvelopeFilename := filepath.Join(workDir, "app.envelope")
	appEnvelope := fmt.Sprintf("{\"Title\":\"BINARYD\", \"Args\":[\"--name=%s\", \"--root-dir=./binstore\", \"--v23.tcp.address=127.0.0.1:0\", \"--http=127.0.0.1:0\"], \"Binary\":{\"File\":%q}, \"Env\":[]}", appPubName, sampleAppBinName)
	ioutil.WriteFile(appEnvelopeFilename, []byte(appEnvelope), 0666)
	defer os.Remove(appEnvelopeFilename)

	output := applicationBin.Run("put", sampleAppName, deviceProfile, appEnvelopeFilename)
	if got, want := output, "Application envelope added successfully."; got != want {
		i.Fatalf("got %q, want %q", got, want)
	}

	// Verify that the envelope we uploaded shows up with glob.
	inv = applicationBin.Start("match", sampleAppName, deviceProfile)
	parts = inv.ExpectSetEventuallyRE(`"Title": "(.*)",`, `"File": "(.*)",`)
	if got, want := len(parts), 2; got != want {
		i.Fatalf("got %d, want %d", got, want)
	}
	for line, want := range []string{"BINARYD", sampleAppBinName} {
		if got := parts[line][1]; got != want {
			i.Fatalf("got %q, want %q", got, want)
		}
	}

	// Install the app on the device.
	inv = deviceBin.Start("install", mtName+"/devmgr/apps", sampleAppName)
	installationName := inv.ReadLine()
	if installationName == "" {
		i.Fatalf("got empty installation name from install")
	}

	// Verify that the installation shows up when globbing the device manager.
	output = namespaceBin.Run("glob", mtName+"/devmgr/apps/BINARYD/*")
	if got, want := output, installationName; got != want {
		i.Fatalf("got %q, want %q", got, want)
	}

	// Start an instance of the app, granting it blessing extension myapp.
	inv = deviceBin.Start("instantiate", installationName, "myapp")
	instanceName := inv.ReadLine()
	if instanceName == "" {
		i.Fatalf("got empty instance name from new")
	}
	deviceBin.Start("run", instanceName)

	resolve(mtName + "/" + appPubName)

	// Verify that the instance shows up when globbing the device manager.
	output = namespaceBin.Run("glob", mtName+"/devmgr/apps/BINARYD/*/*")
	if got, want := output, instanceName; got != want {
		i.Fatalf("got %q, want %q", got, want)
	}

	inv = debugBin.Start("stats", "read", instanceName+"/stats/system/pid")
	pid := inv.ExpectRE("[0-9]+$", 1)[0][0]
	uname, err := getUserForPid(i, pid)
	if err != nil {
		i.Errorf("getUserForPid could not determine the user running pid %v", pid)
	}
	if uname != appUserFlag {
		i.Errorf("app expected to be running as %v but is running as %v", appUserFlag, uname)
	}

	// Verify the app's default blessing.
	inv = debugBin.Start("stats", "read", instanceName+"/stats/security/principal/*/blessingstore")
	inv.ExpectSetEventuallyRE(".*Default Blessings[ ]+root/alice/myapp$")

	// Kill and delete the instance.
	deviceBin.Run("kill", instanceName)
	deviceBin.Run("delete", instanceName)

	// Verify that logs, but not stats, show up when globbing the
	// not-running instance.
	if output = namespaceBin.Run("glob", instanceName+"/stats/..."); len(output) > 0 {
		i.Fatalf("no output expected for glob %s/stats/..., got %q", output, instanceName)
	}
	if output = namespaceBin.Run("glob", instanceName+"/logs/..."); len(output) == 0 {
		i.Fatalf("output expected for glob %s/logs/..., but got none", instanceName)
	}

	// Upload a deviced binary
	devicedAppBinName := binarydName + "/deviced"
	binaryBin.Run("upload", devicedAppBinName, i.BuildGoPkg("v.io/x/ref/services/device/deviced").Path())

	// Upload a device manager envelope.
	devicedEnvelopeFilename := filepath.Join(workDir, "deviced.envelope")
	devicedEnvelope := fmt.Sprintf("{\"Title\":\"device manager\", \"Binary\":{\"File\":%q}}", devicedAppBinName)
	ioutil.WriteFile(devicedEnvelopeFilename, []byte(devicedEnvelope), 0666)
	defer os.Remove(devicedEnvelopeFilename)
	applicationBin.Run("put", devicedAppName, deviceProfile, devicedEnvelopeFilename)

	// Update the device manager.
	deviceBin.Run("update", mtName+"/devmgr/device")
	mtEP = resolveChange(mtName, mtEP)

	// Verify that device manager's mounttable is still published under the
	// expected name (hostname).
	if namespaceBin.Run("glob", mtName) == "" {
		i.Fatalf("failed to glob %s", mtName)
	}

	// Revert the device manager
	deviceBin.Run("revert", mtName+"/devmgr/device")
	mtEP = resolveChange(mtName, mtEP)

	// Verify that device manager's mounttable is still published under the
	// expected name (hostname).
	if namespaceBin.Run("glob", mtName) == "" {
		i.Fatalf("failed to glob %s", mtName)
	}

	// Verify that the local mounttable exists, and that the device manager,
	// the global namespace, and the neighborhood are mounted on it.
	n := mtEP + "/devmgr"
	if namespaceBin.Run("resolve", n) == "" {
		i.Fatalf("failed to resolve %s", n)
	}
	n = mtEP + "/nh"
	if namespaceBin.Run("resolve", n) == "" {
		i.Fatalf("failed to resolve %s", n)
	}
	namespaceRoot, _ := i.GetVar(envvar.NamespacePrefix)
	n = mtEP + "/global"
	if got, want := namespaceBin.Run("resolve", n), namespaceRoot; got != want {
		i.Fatalf("got %q, want %q", got, want)
	}

	// Kill the device manager (which causes it to be restarted), wait for
	// the endpoint to change.
	deviceBin.Run("kill", mtName+"/devmgr/device")
	mtEP = resolveChange(mtName, mtEP)

	// Shut down the device manager.
	deviceScript.Run("stop")

	// Wait for the mounttable entry to go away.
	resolveGone := func(name string) string {
		resolver := func() (interface{}, error) {
			inv := namespaceBin.Start("resolve", name)
			defer inv.Wait(nil, os.Stderr)
			if r := strings.TrimRight(inv.Output(), "\n"); len(r) == 0 {
				return r, nil
			}
			return nil, nil
		}
		return i.WaitFor(resolver, 100*time.Millisecond, time.Minute).(string)
	}
	resolveGone(mtName)

	var fi []os.FileInfo

	// This doesn't work in multiuser mode because dmInstallDir is
	// owned by the device manager user and unreadable by the user
	// running this test.
	if !withSuid {
		fi, err = ioutil.ReadDir(dmInstallDir)
		if err != nil {
			i.Fatalf("failed to readdir for %q: %v", dmInstallDir, err)
		}
	}

	deviceScript.Run("uninstall")

	fi, err = ioutil.ReadDir(dmInstallDir)
	if err == nil || len(fi) > 0 {
		i.Fatalf("managed to read %d entries from %q", len(fi), dmInstallDir)
	}
	if err != nil && !strings.Contains(err.Error(), "no such file or directory") {
		i.Fatalf("wrong error: %v", err)
	}
}

func buildAndCopyBinaries(i *v23tests.T, destinationDir string, packages ...string) {
	var args []string
	for _, pkg := range packages {
		args = append(args, i.BuildGoPkg(pkg).Path())
	}
	args = append(args, destinationDir)
	i.BinaryFromPath("/bin/cp").Start(args...).WaitOrDie(os.Stdout, os.Stderr)
}

func mkSubdir(i *v23tests.T, parent, child string) string {
	dir := filepath.Join(parent, child)
	if err := os.Mkdir(dir, 0755); err != nil {
		i.Fatalf("failed to create %q: %v", dir, err)
	}
	return dir
}

var re = regexp.MustCompile("[ \t]+")

// getUserForPid determines the username running process pid.
func getUserForPid(i *v23tests.T, pid string) (string, error) {
	pidString := i.BinaryFromPath("/bin/ps").Start(psFlags).Output()
	for _, line := range strings.Split(pidString, "\n") {
		fields := re.Split(line, -1)
		if len(fields) > 1 && pid == fields[1] {
			return fields[0], nil
		}
	}
	return "", fmt.Errorf("Couldn't determine the user for pid %s", pid)
}
