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

package servicetest

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/options"
	"v.io/x/lib/gosh"
	"v.io/x/ref"
	"v.io/x/ref/internal/logger"
	"v.io/x/ref/lib/signals"
	"v.io/x/ref/services/internal/dirprinter"
	"v.io/x/ref/services/mounttable/mounttablelib"
	"v.io/x/ref/test"
	"v.io/x/ref/test/testutil"
	"v.io/x/ref/test/v23test"
)

const (
	// Setting this environment variable to any non-empty value avoids
	// removing the generated workspace for successful test runs (for
	// failed test runs, this is already the case).  This is useful when
	// developing test cases.
	preserveWorkspaceEnv = "V23_TEST_PRESERVE_WORKSPACE"
)

var rootMT = gosh.RegisterFunc("rootMT", func() error {
	ctx, shutdown := test.V23Init()
	defer shutdown()
	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
	if err != nil {
		return fmt.Errorf("mounttablelib.NewMountTableDispatcher failed: %s", err)
	}
	ctx, server, err := v23.WithNewDispatchingServer(ctx, "", mt, options.ServesMountTable(true))
	if err != nil {
		return fmt.Errorf("rootMT failed: %v", err)
	}
	gosh.SendVars(map[string]string{"NAME": server.Status().Endpoints[0].Name()})
	<-signals.ShutdownOnSignals(ctx)
	return nil
})

// startRootMT sets up a root mount table for tests.
func startRootMT(t *testing.T, sh *v23test.Shell) string {
	c := sh.FuncCmd(rootMT)
	c.Args = append(c.Args, "--v23.tcp.address=127.0.0.1:0")
	c.PropagateOutput = false
	c.Start()
	return c.AwaitVars("NAME")["NAME"]
}

// setNSRoots sets the roots for the local runtime's namespace.
func setNSRoots(t *testing.T, ctx *context.T, roots ...string) {
	ns := v23.GetNamespace(ctx)
	if err := ns.SetRoots(roots...); err != nil {
		t.Fatal(testutil.FormatLogLine(3, "SetRoots(%v) failed: %v", roots, err))
	}
}

// CreateShellAndMountTable builds a new shell and starts a root mount table.
// Returns the shell and a cleanup function.
// TODO(sadovsky): Use v23test.StartRootMountTable.
func CreateShellAndMountTable(t *testing.T, ctx *context.T) (*v23test.Shell, func()) {
	sh := v23test.NewShell(t, ctx)
	sh.PropagateChildOutput = true
	ok := false
	defer func() {
		if !ok {
			sh.Cleanup()
		}
	}()
	mtName := startRootMT(t, sh)
	ctx.VI(1).Infof("Started root mount table with name %s", mtName)
	oldNamespaceRoots := v23.GetNamespace(ctx).Roots()
	fn := func() {
		ctx.VI(1).Info("------------ CLEANUP ------------")
		ctx.VI(1).Info("---------------------------------")
		ctx.VI(1).Info("--(cleaning up shell)------------")
		sh.Cleanup()
		ctx.VI(1).Info("--(done cleaning up shell)-------")
		setNSRoots(t, ctx, oldNamespaceRoots...)
	}
	setNSRoots(t, ctx, mtName)
	sh.Vars[ref.EnvNamespacePrefix] = mtName
	ok = true
	return sh, fn
}

// CreateShell builds a new shell.
// Returns the shell and a cleanup function.
func CreateShell(t *testing.T, ctx *context.T) (*v23test.Shell, func()) {
	sh := v23test.NewShell(t, ctx)
	sh.PropagateChildOutput = true
	ok := false
	defer func() {
		if !ok {
			sh.Cleanup()
		}
	}()
	fn := func() {
		ctx.VI(1).Info("------------ CLEANUP ------------")
		ctx.VI(1).Info("---------------------------------")
		ctx.VI(1).Info("--(cleaning up shell)------------")
		sh.Cleanup()
		ctx.VI(1).Info("--(done cleaning up shell)-------")
	}
	nsRoots := v23.GetNamespace(ctx).Roots()
	if len(nsRoots) == 0 {
		t.Fatalf("no namespace roots")
	}
	sh.Vars[ref.EnvNamespacePrefix] = nsRoots[0]
	ok = true
	return sh, fn
}

// SetupRootDir sets up and returns a directory for the root and returns
// a cleanup function.
func SetupRootDir(t *testing.T, prefix string) (string, func()) {
	rootDir, err := ioutil.TempDir("", prefix)
	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 {
		logger.Global().Fatalf("EvalSymlinks(%v) failed: %v", rootDir, err)
	}
	return rootDir, func() {
		if t.Failed() || os.Getenv(preserveWorkspaceEnv) != "" {
			t.Logf("A dump of the %s workspace at %v:", prefix, rootDir)
			var dump bytes.Buffer
			if err := dirprinter.DumpDir(&dump, rootDir); err != nil {
				t.Logf("Failed to dump %v: %v", rootDir, err)
			} else {
				t.Log("\n" + dump.String())
			}
		} else {
			os.RemoveAll(rootDir)
		}
	}
}
