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

//go:generate v23 test generate .

import (
	"fmt"
	"os"

	"v.io/v23/security"
	"v.io/x/ref"
	vsecurity "v.io/x/ref/lib/security"
	"v.io/x/ref/test/v23tests"
)

func V23TestAgentd(t *v23tests.T) {
	var (
		clientAgent, serverAgent = createClientAndServerAgents(t)
		tmpdir                   = t.NewTempDir("")
		vrun                     = t.BuildGoPkg("v.io/x/ref/cmd/vrun").Path()
		pingpong                 = t.BuildGoPkg("v.io/x/ref/services/agent/internal/pingpong").Path()
		serverName               = serverAgent.Start(pingpong).ExpectVar("NAME")

		tests = []struct {
			Command []string
			Client  string
		}{
			{
				[]string{pingpong, serverName}, // No vrun
				"pingpongd/client",
			},
			{
				[]string{vrun, pingpong, serverName},
				"pingpongd/client/pingpong",
			},
			{
				[]string{vrun, "--name=bugsy", pingpong, serverName},
				"pingpongd/client/bugsy",
			},
		}
	)
	for _, test := range tests {
		args := append([]string{"--additional-principals=" + tmpdir}, test.Command...)
		client := clientAgent.Start(args...)
		client.Expect("Pinging...")
		client.Expect(fmt.Sprintf("pong (client:[%v] server:[pingpongd])", test.Client))
		client.WaitOrDie(os.Stdout, os.Stderr)
		if err := client.Error(); err != nil {
			t.Errorf("Test: %+v: %v", test, err)
		}
	}
}

// createClientAndServerAgents creates two principals, sets up their
// blessings and returns the agent binaries that will use the created credentials.
//
// The server will have a single blessing "pingpongd".
// The client will have a single blessing "pingpongd/client", blessed by the server.
func createClientAndServerAgents(i *v23tests.T) (client, server *v23tests.Binary) {
	var (
		agentd    = i.BuildGoPkg("v.io/x/ref/services/agent/agentd")
		clientDir = i.NewTempDir("")
		serverDir = i.NewTempDir("")
	)
	pserver, err := vsecurity.CreatePersistentPrincipal(serverDir, nil)
	if err != nil {
		i.Fatal(err)
	}
	pclient, err := vsecurity.CreatePersistentPrincipal(clientDir, nil)
	if err != nil {
		i.Fatal(err)
	}
	// Server will only serve, not make any client requests, so only needs a default blessing.
	bserver, err := pserver.BlessSelf("pingpongd")
	if err != nil {
		i.Fatal(err)
	}
	if err := pserver.BlessingStore().SetDefault(bserver); err != nil {
		i.Fatal(err)
	}
	// Clients need not have a default blessing as they will only make a request to the server.
	bclient, err := pserver.Bless(pclient.PublicKey(), bserver, "client", security.UnconstrainedUse())
	if err != nil {
		i.Fatal(err)
	}
	if _, err := pclient.BlessingStore().Set(bclient, "pingpongd"); err != nil {
		i.Fatal(err)
	}
	// The client and server must both recognize bserver and its delegates.
	if err := pserver.AddToRoots(bserver); err != nil {
		i.Fatal(err)
	}
	if err := pclient.AddToRoots(bserver); err != nil {
		i.Fatal(err)
	}
	// We need to add set a default blessings to this pclient for this principal to
	// work with vrun.
	if err := pclient.BlessingStore().SetDefault(bclient); err != nil {
		i.Fatal(err)
	}
	return agentd.WithEnv(ref.EnvCredentials + "=" + clientDir), agentd.WithEnv(ref.EnvCredentials + "=" + serverDir)
}
