package impl_test

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"sort"
	"strings"
	"testing"
	"time"

	"veyron.io/veyron/veyron2"
	"veyron.io/veyron/veyron2/ipc"
	"veyron.io/veyron/veyron2/naming"
	"veyron.io/veyron/veyron2/security"
	"veyron.io/veyron/veyron2/services/mgmt/device"
	"veyron.io/veyron/veyron2/verror"
	"veyron.io/veyron/veyron2/verror2"
	"veyron.io/veyron/veyron2/vlog"

	"veyron.io/veyron/veyron/lib/expect"
	"veyron.io/veyron/veyron/lib/flags/consts"
	"veyron.io/veyron/veyron/lib/modules"
	"veyron.io/veyron/veyron/lib/modules/core"
	tsecurity "veyron.io/veyron/veyron/lib/testutil/security"
	"veyron.io/veyron/veyron/profiles/static"
	"veyron.io/veyron/veyron/services/mgmt/device/impl"
	"veyron.io/veyron/veyron2/services/mgmt/application"
)

const (
	// Setting this environment variable to any non-empty value avoids
	// removing the device manager's workspace for successful test runs (for
	// failed test runs, this is already the case).  This is useful when
	// developing test cases.
	preserveDMWorkspaceEnv = "VEYRON_TEST_PRESERVE_DM_WORKSPACE"

	// TODO(caprita): Set the timeout in a more principled manner.
	expectTimeout = 20 * time.Second
)

func loc(d int) string {
	_, file, line, _ := runtime.Caller(d + 1)
	return fmt.Sprintf("%s:%d", filepath.Base(file), line)
}

func startRootMT(t *testing.T, sh *modules.Shell) (string, modules.Handle) {
	h, err := sh.Start(core.RootMTCommand, nil, "--", "--veyron.tcp.address=127.0.0.1:0")
	if err != nil {
		t.Fatalf("failed to start root mount table: %s", err)
	}
	s := expect.NewSession(t, h.Stdout(), expectTimeout)
	rootName := s.ExpectVar("MT_NAME")
	if t.Failed() {
		t.Fatalf("failed to read mt name: %s", s.Error())
	}
	return rootName, h
}

func credentialsForChild(blessing string) (string, []string) {
	creds, _ := tsecurity.ForkCredentials(globalRT.Principal(), blessing)
	return creds, []string{consts.VeyronCredentials + "=" + creds}
}

// setNSRoots sets the roots for the local runtime's namespace.
func setNSRoots(t *testing.T, roots ...string) {
	if err := globalRT.Namespace().SetRoots(roots...); err != nil {
		t.Fatalf("%s: SetRoots(%v) failed with %v", loc(2), roots, err)
	}
}

func createShellAndMountTable(t *testing.T) (*modules.Shell, func()) {
	sh, err := modules.NewShell(nil)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	// The shell, will, by default share credentials with its children.
	sh.ClearVar(consts.VeyronCredentials)

	mtName, mtHandle := startRootMT(t, sh)
	vlog.VI(1).Infof("Started shell mounttable with name %v", mtName)
	// Make sure the root mount table is the last process to be shutdown
	// since the others will likely want to communicate with it during
	// their shutdown process
	sh.Forget(mtHandle)

	// TODO(caprita): Define a GetNamespaceRootsCommand in modules/core and
	// use that?
	oldNamespaceRoots := globalRT.Namespace().Roots()
	fn := func() {
		vlog.VI(1).Info("------------ CLEANUP ------------")
		vlog.VI(1).Info("---------------------------------")
		vlog.VI(1).Info("--(cleaning up shell)------------")
		if err := sh.Cleanup(os.Stdout, os.Stderr); err != nil {
			t.Fatalf("sh.Cleanup failed with %v", err)
		}
		vlog.VI(1).Info("--(done cleaning up shell)-------")
		vlog.VI(1).Info("--(shutting down root mt)--------")
		if err := mtHandle.Shutdown(os.Stdout, os.Stderr); err != nil {
			t.Fatalf("mtHandle.Shutdown failed with %v", err)
		}
		vlog.VI(1).Info("--(done shutting down root mt)---")
		vlog.VI(1).Info("--------- DONE CLEANUP ----------")
		setNSRoots(t, oldNamespaceRoots...)
	}
	setNSRoots(t, mtName)
	sh.SetVar(consts.NamespaceRootPrefix, mtName)
	return sh, fn
}

func runShellCommand(t *testing.T, sh *modules.Shell, env []string, cmd string, args ...string) (modules.Handle, *expect.Session) {
	h, err := sh.Start(cmd, env, args...)
	if err != nil {
		t.Fatalf("%s: failed to start %q: %s", loc(1), cmd, err)
		return nil, nil
	}
	s := expect.NewSession(t, h.Stdout(), expectTimeout)
	s.SetVerbosity(testing.Verbose())
	return h, s
}

func envelopeFromShell(sh *modules.Shell, env []string, cmd, title string, args ...string) application.Envelope {
	args, nenv := sh.CommandEnvelope(cmd, env, args...)
	return application.Envelope{
		Title: title,
		Args:  args[1:],
		// TODO(caprita): revisit how the environment is sanitized for arbirary
		// apps.
		Env:    impl.VeyronEnvironment(nenv),
		Binary: mockBinaryRepoName,
	}
}

// setupRootDir sets up and returns the local filesystem location that the
// device manager is told to use, as well as a cleanup function.
func setupRootDir(t *testing.T) (string, func()) {
	rootDir, err := ioutil.TempDir("", "devicemanager")
	if err != nil {
		t.Fatalf("Failed to set up temporary dir for test: %v", err)
	}
	// On some operating systems (e.g. darwin) os.TempDir() can return a
	// symlink. To avoid having to account for this eventuality later,
	// evaluate the symlink.
	rootDir, err = filepath.EvalSymlinks(rootDir)
	if err != nil {
		vlog.Fatalf("EvalSymlinks(%v) failed: %v", rootDir, err)
	}
	return rootDir, func() {
		if t.Failed() || os.Getenv(preserveDMWorkspaceEnv) != "" {
			t.Logf("You can examine the device manager workspace at %v", rootDir)
		} else {
			os.RemoveAll(rootDir)
		}
	}
}

func newServer() (ipc.Server, string) {
	server, err := globalRT.NewServer()
	if err != nil {
		vlog.Fatalf("NewServer() failed: %v", err)
	}
	spec := static.ListenSpec
	spec.Address = "127.0.0.1:0" // Isn't this the default?
	endpoint, err := server.Listen(spec)
	if err != nil {
		vlog.Fatalf("Listen(%s) failed: %v", static.ListenSpec, err)
	}
	return server, endpoint.String()
}

// resolveExpectNotFound verifies that the given name is not in the mounttable.
func resolveExpectNotFound(t *testing.T, name string) {
	if results, err := globalRT.Namespace().Resolve(globalRT.NewContext(), name); err == nil {
		t.Fatalf("%s: Resolve(%v) succeeded with results %v when it was expected to fail", loc(1), name, results)
	} else if expectErr := naming.ErrNoSuchName.ID; !verror2.Is(err, expectErr) {
		t.Fatalf("%s: Resolve(%v) failed with error %v, expected error ID %v", loc(1), name, err, expectErr)
	}
}

// resolve looks up the given name in the mounttable.
func resolve(t *testing.T, name string, replicas int) []string {
	results, err := globalRT.Namespace().Resolve(globalRT.NewContext(), name)
	if err != nil {
		t.Fatalf("Resolve(%v) failed: %v", name, err)
	}

	filteredResults := []string{}
	for _, r := range results {
		if strings.Index(r, "@tcp") != -1 {
			filteredResults = append(filteredResults, r)
		}
	}
	// We are going to get a websocket and a tcp endpoint for each replica.
	if want, got := replicas, len(filteredResults); want != got {
		t.Fatalf("Resolve(%v) expected %d result(s), got %d instead", name, want, got)
	}
	return filteredResults
}

// The following set of functions are convenience wrappers around Update and
// Revert for device manager.

func deviceStub(name string) device.DeviceClientMethods {
	deviceName := naming.Join(name, "device")
	return device.DeviceClient(deviceName)
}

func updateDeviceExpectError(t *testing.T, name string, errID verror.ID) {
	if err := deviceStub(name).Update(globalRT.NewContext()); !verror2.Is(err, errID) {
		t.Fatalf("%s: Update(%v) expected to fail with %v, got %v instead", loc(1), name, errID, err)
	}
}

func updateDevice(t *testing.T, name string) {
	if err := deviceStub(name).Update(globalRT.NewContext()); err != nil {
		t.Fatalf("%s: Update(%v) failed: %v", loc(1), name, err)
	}
}

func revertDeviceExpectError(t *testing.T, name string, errID verror.ID) {
	if err := deviceStub(name).Revert(globalRT.NewContext()); !verror2.Is(err, errID) {
		t.Fatalf("%s: Revert(%v) expected to fail with %v, got %v instead", loc(1), name, errID, err)
	}
}

func revertDevice(t *testing.T, name string) {
	if err := deviceStub(name).Revert(globalRT.NewContext()); err != nil {
		t.Fatalf("%s: Revert(%v) failed: %v", loc(1), name, err)
	}
}

// The following set of functions are convenience wrappers around various app
// management methods.

func ort(opt []veyron2.Runtime) veyron2.Runtime {
	if len(opt) > 0 {
		return opt[0]
	} else {
		return globalRT
	}
}

func appStub(nameComponents ...string) device.ApplicationClientMethods {
	appsName := "dm//apps"
	appName := naming.Join(append([]string{appsName}, nameComponents...)...)
	return device.ApplicationClient(appName)
}

func installApp(t *testing.T, opt ...veyron2.Runtime) string {
	appID, err := appStub().Install(ort(opt).NewContext(), mockApplicationRepoName)
	if err != nil {
		t.Fatalf("%s: Install failed: %v", loc(1), err)
	}
	return appID
}

type granter struct {
	ipc.CallOpt
	p         security.Principal
	extension string
}

func (g *granter) Grant(other security.Blessings) (security.Blessings, error) {
	return g.p.Bless(other.PublicKey(), g.p.BlessingStore().Default(), g.extension, security.UnconstrainedUse())
}

func startAppImpl(t *testing.T, appID, grant string, opt ...veyron2.Runtime) (string, error) {
	var opts []ipc.CallOpt
	if grant != "" {
		opts = append(opts, &granter{p: ort(opt).Principal(), extension: grant})
	}
	if instanceIDs, err := appStub(appID).Start(ort(opt).NewContext(), opts...); err != nil {
		return "", err
	} else {
		if want, got := 1, len(instanceIDs); want != got {
			t.Fatalf("%s: Start(%v): expected %v instance ids, got %v instead", loc(1), appID, want, got)
		}
		return instanceIDs[0], nil
	}
}

func startApp(t *testing.T, appID string, opt ...veyron2.Runtime) string {
	instanceID, err := startAppImpl(t, appID, "forapp", opt...)
	if err != nil {
		t.Fatalf("%s: Start(%v) failed: %v", loc(1), appID, err)
	}
	return instanceID
}

func startAppExpectError(t *testing.T, appID string, expectedError verror.ID, opt ...veyron2.Runtime) {
	if _, err := startAppImpl(t, appID, "forapp", opt...); err == nil || !verror2.Is(err, expectedError) {
		t.Fatalf("%s: Start(%v) expected to fail with %v, got %v instead", loc(1), appID, expectedError, err)
	}
}

func stopApp(t *testing.T, appID, instanceID string, opt ...veyron2.Runtime) {
	if err := appStub(appID, instanceID).Stop(ort(opt).NewContext(), 5); err != nil {
		t.Fatalf("%s: Stop(%v/%v) failed: %v", loc(1), appID, instanceID, err)
	}
}

func suspendApp(t *testing.T, appID, instanceID string, opt ...veyron2.Runtime) {
	if err := appStub(appID, instanceID).Suspend(ort(opt).NewContext()); err != nil {
		t.Fatalf("%s: Suspend(%v/%v) failed: %v", loc(1), appID, instanceID, err)
	}
}

func resumeApp(t *testing.T, appID, instanceID string, opt ...veyron2.Runtime) {
	if err := appStub(appID, instanceID).Resume(ort(opt).NewContext()); err != nil {
		t.Fatalf("%s: Resume(%v/%v) failed: %v", loc(1), appID, instanceID, err)
	}
}

func resumeAppExpectError(t *testing.T, appID, instanceID string, expectedError verror.ID, opt ...veyron2.Runtime) {
	if err := appStub(appID, instanceID).Resume(ort(opt).NewContext()); err == nil || !verror2.Is(err, expectedError) {
		t.Fatalf("%s: Resume(%v/%v) expected to fail with %v, got %v instead", loc(1), appID, instanceID, expectedError, err)
	}
}

func updateApp(t *testing.T, appID string, opt ...veyron2.Runtime) {
	if err := appStub(appID).Update(ort(opt).NewContext()); err != nil {
		t.Fatalf("%s: Update(%v) failed: %v", loc(1), appID, err)
	}
}

func updateAppExpectError(t *testing.T, appID string, expectedError verror.ID) {
	if err := appStub(appID).Update(globalRT.NewContext()); err == nil || !verror2.Is(err, expectedError) {
		t.Fatalf("%s: Update(%v) expected to fail with %v, got %v instead", loc(1), appID, expectedError, err)
	}
}

func revertApp(t *testing.T, appID string) {
	if err := appStub(appID).Revert(globalRT.NewContext()); err != nil {
		t.Fatalf("%s: Revert(%v) failed: %v", loc(1), appID, err)
	}
}

func revertAppExpectError(t *testing.T, appID string, expectedError verror.ID) {
	if err := appStub(appID).Revert(globalRT.NewContext()); err == nil || !verror2.Is(err, expectedError) {
		t.Fatalf("%s: Revert(%v) expected to fail with %v, got %v instead", loc(1), appID, expectedError, err)
	}
}

func uninstallApp(t *testing.T, appID string) {
	if err := appStub(appID).Uninstall(globalRT.NewContext()); err != nil {
		t.Fatalf("%s: Uninstall(%v) failed: %v", loc(1), appID, err)
	}
}

// Code to make Association lists sortable.
type byIdentity []device.Association

func (a byIdentity) Len() int           { return len(a) }
func (a byIdentity) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byIdentity) Less(i, j int) bool { return a[i].IdentityName < a[j].IdentityName }

func compareAssociations(t *testing.T, got, expected []device.Association) {
	sort.Sort(byIdentity(got))
	sort.Sort(byIdentity(expected))
	if !reflect.DeepEqual(got, expected) {
		t.Fatalf("ListAssociations() got %v, expected %v", got, expected)
	}
}

// generateSuidHelperScript builds a script to execute the test target as
// a suidhelper instance and returns the path to the script.
func generateSuidHelperScript(t *testing.T, root string) string {
	output := "#!/bin/bash\n"
	output += "VEYRON_SUIDHELPER_TEST=1"
	output += " "
	output += "exec " + os.Args[0] + " -minuid=1 -test.run=TestSuidHelper $*"
	output += "\n"

	vlog.VI(1).Infof("script\n%s", output)

	if err := os.MkdirAll(root, 0755); err != nil {
		t.Fatalf("MkdirAll failed: %v", err)
	}
	// Helper does not need to live under the device manager's root dir, but
	// we put it there for convenience.
	path := filepath.Join(root, "helper.sh")
	if err := ioutil.WriteFile(path, []byte(output), 0755); err != nil {
		t.Fatalf("WriteFile(%v) failed: %v", path, err)
	}
	return path
}
