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

// The following enables go generate to generate the doc.go file.
//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help

package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/x/lib/cmdline"
	"v.io/x/ref"
	vsecurity "v.io/x/ref/lib/security"
	"v.io/x/ref/lib/v23cmd"
	"v.io/x/ref/services/agent/internal/ipc"
	"v.io/x/ref/services/agent/internal/server"
	"v.io/x/ref/services/role"

	_ "v.io/x/ref/runtime/factories/generic"
)

var (
	durationFlag time.Duration
	nameFlag     string
	roleFlag     string
)

var cmdVbecome = &cmdline.Command{
	Runner:   v23cmd.RunnerFunc(vbecome),
	Name:     "vbecome",
	Short:    "executes commands with a derived Vanadium principal",
	Long:     "Command vbecome executes commands with a derived Vanadium principal.",
	ArgsName: "<command> [command args...]",
}

const childAgentFd = 3
const keyServerFd = 4

func main() {
	cmdline.HideGlobalFlagsExcept()
	syscall.CloseOnExec(childAgentFd)
	syscall.CloseOnExec(keyServerFd)

	cmdVbecome.Flags.DurationVar(&durationFlag, "duration", 1*time.Hour, "Duration for the blessing.")
	cmdVbecome.Flags.StringVar(&nameFlag, "name", "", "Name to use for the blessing.")
	cmdVbecome.Flags.StringVar(&roleFlag, "role", "", "Role object from which to request the blessing. If set, the blessings from this role server are used and --name is ignored. If not set, the default blessings of the calling principal are extended with --name.")

	cmdline.Main(cmdVbecome)
}

func vbecome(ctx *context.T, env *cmdline.Env, args []string) error {
	if len(args) == 0 {
		if shell := env.Vars["SHELL"]; shell != "" {
			args = []string{shell}
		} else {
			return fmt.Errorf("You must specify a command to run.")
		}
	}

	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		return err
	}
	signer := security.NewInMemoryECDSASigner(key)
	principal, err := vsecurity.NewPrincipalFromSigner(signer, nil)
	if err != nil {
		return err
	}

	if len(roleFlag) == 0 {
		if len(nameFlag) == 0 {
			nameFlag = filepath.Base(args[0])
		}
		if err := bless(ctx, principal, nameFlag); err != nil {
			return err
		}
		ctx, err = v23.WithPrincipal(ctx, principal)
		if err != nil {
			return err
		}
	} else {
		// The role server expects the client's blessing name to end
		// with RoleSuffix. This is to avoid accidentally granting role
		// access to anything else that might have been blessed by the
		// same principal.
		if err := bless(ctx, principal, role.RoleSuffix); err != nil {
			return err
		}
		ctx, err = v23.WithPrincipal(ctx, principal)
		if err != nil {
			return err
		}
		if err = setupRoleBlessings(ctx, roleFlag); err != nil {
			return err
		}
	}

	// Start an agent server.
	i := ipc.NewIPC()
	if err := server.ServeAgent(i, principal); err != nil {
		return err
	}
	dir, err := ioutil.TempDir("", "vbecome")
	if err != nil {
		return err
	}
	defer os.RemoveAll(dir)
	path := filepath.Join(dir, "sock")
	if err := i.Listen(path); err != nil {
		return err
	}
	defer i.Close()
	if err = os.Setenv(ref.EnvAgentPath, path); err != nil {
		ctx.Fatalf("setenv: %v", err)
	}

	return doExec(args)
}

func bless(ctx *context.T, p security.Principal, name string) error {
	caveat, err := security.NewExpiryCaveat(time.Now().Add(durationFlag))
	if err != nil {
		ctx.Errorf("Couldn't create caveat")
		return err
	}

	rp := v23.GetPrincipal(ctx)
	blessing, err := rp.Bless(p.PublicKey(), rp.BlessingStore().Default(), name, caveat)
	if err != nil {
		ctx.Errorf("Couldn't bless")
		return err
	}

	if err = p.BlessingStore().SetDefault(blessing); err != nil {
		ctx.Errorf("Couldn't set default blessing")
		return err
	}
	if _, err = p.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
		ctx.Errorf("Couldn't set default client blessing")
		return err
	}
	if err = p.AddToRoots(blessing); err != nil {
		ctx.Errorf("Couldn't set trusted roots")
		return err
	}
	return nil
}

func doExec(args []string) error {
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

func setupRoleBlessings(ctx *context.T, roleStr string) error {
	b, err := role.RoleClient(roleStr).SeekBlessings(ctx)
	if err != nil {
		return err
	}
	p := v23.GetPrincipal(ctx)
	// TODO(rthellend,ashankar): Revisit this configuration.
	// SetDefault: Should we expect users to want to act as a server on behalf of the role (by default?)
	// AllPrincipals: Do we not want to be discriminating about which services we use the role blessing at.
	if err := p.BlessingStore().SetDefault(b); err != nil {
		return err
	}
	if _, err := p.BlessingStore().Set(b, security.AllPrincipals); err != nil {
		return err
	}
	return nil
}
