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

import (
	"fmt"
	"os"
	goexec "os/exec"
	"strings"
	"testing"

	"v.io/v23"
	"v.io/v23/naming"
	"v.io/v23/rpc"

	"v.io/x/lib/vlog"

	"v.io/x/ref/lib/signals"
	"v.io/x/ref/services/device/internal/config"
	"v.io/x/ref/services/device/internal/impl"
	"v.io/x/ref/services/device/internal/starter"
	"v.io/x/ref/services/device/internal/suid"
	"v.io/x/ref/test"
	"v.io/x/ref/test/modules"
)

const (
	RedirectEnv    = "DEVICE_MANAGER_DONT_REDIRECT_STDOUT_STDERR"
	TestEnvVarName = "V23_RANDOM_ENV_VALUE"
	NoPairingToken = ""
)

// ExecScript launches the script passed as argument.
var ExecScript = modules.Register(func(env *modules.Env, args ...string) error {
	if want, got := 1, len(args); want != got {
		vlog.Fatalf("ExecScript expected %d arguments, got %d instead", want, got)
	}
	script := args[0]
	osenv := []string{RedirectEnv + "=1"}
	if env.Vars["PAUSE_BEFORE_STOP"] == "1" {
		osenv = append(osenv, "PAUSE_BEFORE_STOP=1")
	}

	cmd := goexec.Cmd{
		Path:   script,
		Env:    osenv,
		Stdin:  env.Stdin,
		Stderr: env.Stderr,
		Stdout: env.Stdout,
	}
	return cmd.Run()
}, "ExecScript")

// DeviceManager sets up a device manager server.  It accepts the name to
// publish the server under as an argument.  Additional arguments can optionally
// specify device manager config settings.
var DeviceManager = modules.Register(deviceManagerFunc, "DeviceManager")

func deviceManagerFunc(env *modules.Env, args ...string) error {
	ctx, shutdown := test.V23Init()
	if len(args) == 0 {
		vlog.Fatalf("deviceManager expected at least an argument")
	}
	publishName := args[0]
	args = args[1:]
	defer fmt.Fprintf(env.Stdout, "%v terminated\n", publishName)
	defer vlog.VI(1).Infof("%v terminated", publishName)
	defer shutdown()
	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	// Satisfy the contract described in doc.go by passing the config state
	// through to the device manager dispatcher constructor.
	configState, err := config.Load()
	if err != nil {
		vlog.Fatalf("Failed to decode config state: %v", err)
	}

	// This exemplifies how to override or set specific config fields, if,
	// for example, the device manager is invoked 'by hand' instead of via a
	// script prepared by a previous version of the device manager.
	var pairingToken string
	if len(args) > 0 {
		if want, got := 4, len(args); want > got {
			vlog.Fatalf("expected atleast %d additional arguments, got %d instead: %q", want, got, args)
		}
		configState.Root, configState.Helper, configState.Origin, configState.CurrentLink = args[0], args[1], args[2], args[3]
		if len(args) > 4 {
			pairingToken = args[4]
		}
	}
	// We grab the shutdown channel at this point in order to ensure that we
	// register a listener for the app cycle manager Stop before we start
	// running the device manager service.  Otherwise, any device manager
	// method that calls Stop on the app cycle manager (e.g. the Stop RPC)
	// will precipitate an immediate process exit.
	shutdownChan := signals.ShutdownOnSignals(ctx)
	claimableName, stop, err := starter.Start(ctx, starter.Args{
		Namespace: starter.NamespaceArgs{
			ListenSpec: rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}},
		},
		Device: starter.DeviceArgs{
			Name:            publishName,
			ListenSpec:      rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}},
			ConfigState:     configState,
			TestMode:        strings.HasSuffix(fmt.Sprint(v23.GetPrincipal(ctx).BlessingStore().Default()), "/testdm"),
			RestartCallback: func() { fmt.Println("restart handler") },
			PairingToken:    pairingToken,
		},
		// TODO(rthellend): Wire up the local mounttable like the real device
		// manager, i.e. mount the device manager and the apps on it, and mount
		// the local mounttable in the global namespace.
		// MountGlobalNamespaceInLocalNamespace: true,
	})
	if err != nil {
		vlog.Errorf("starter.Start failed: %v", err)
		return err
	}
	defer stop()
	// Update the namespace roots to remove the server blessing from the
	// endpoints.  This is needed to be able to publish into the 'global'
	// mounttable before we have compatible credentials.
	ctx, err = SetNamespaceRootsForUnclaimedDevice(ctx)
	if err != nil {
		return err
	}
	// Manually mount the claimable service in the 'global' mounttable.
	v23.GetNamespace(ctx).Mount(ctx, "claimable", claimableName, 0)
	fmt.Fprintf(env.Stdout, "ready:%d\n", os.Getpid())

	<-shutdownChan
	if val, present := env.Vars["PAUSE_BEFORE_STOP"]; present && val == "1" {
		modules.WaitForEOF(env.Stdin)
	}
	// TODO(ashankar): Figure out a way to incorporate this check in the test.
	// if impl.DispatcherLeaking(dispatcher) {
	//	vlog.Fatalf("device manager leaking resources")
	// }
	return nil
}

// This is the same as DeviceManager above, except that it has a different major version number
var DeviceManagerV10 = modules.Register(func(env *modules.Env, args ...string) error {
	impl.CurrentVersion = impl.Version{10, 0} // Set the version number to 10.0
	return deviceManagerFunc(env, args...)
}, "DeviceManagerV10")

func TestMainImpl(m *testing.M) {
	test.Init()
	isSuidHelper := len(os.Getenv("V23_SUIDHELPER_TEST")) > 0
	if modules.IsChildProcess() && !isSuidHelper {
		if err := modules.Dispatch(); err != nil {
			fmt.Fprintf(os.Stderr, "modules.Dispatch failed: %v\n", err)
			os.Exit(1)
		}
		return
	}
	os.Exit(m.Run())
}

// TestSuidHelper is testing boilerplate for suidhelper that does not
// create a runtime because the suidhelper is not a Vanadium application.
func TestSuidHelperImpl(t *testing.T) {
	if os.Getenv("V23_SUIDHELPER_TEST") != "1" {
		return
	}
	vlog.VI(1).Infof("TestSuidHelper starting")
	if err := suid.Run(os.Environ()); err != nil {
		vlog.Fatalf("Failed to Run() setuidhelper: %v", err)
	}
}
