// 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 $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help

package main

import (
	"encoding/base64"
	"io/ioutil"
	"strings"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/vom"
	"v.io/x/lib/cmdline"
	lsecurity "v.io/x/ref/lib/security"
	"v.io/x/ref/lib/signals"
	"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/cluster"

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

var (
	clusterAgent  string
	socketPath    string
	secretKeyFile string
	rootBlessings string
)

func main() {
	cmdPodAgentD.Flags.StringVar(&clusterAgent, "agent", "", "The address of the cluster agent.")
	cmdPodAgentD.Flags.StringVar(&socketPath, "socket-path", "", "The path of the unix socket to listen on.")
	cmdPodAgentD.Flags.StringVar(&secretKeyFile, "secret-key-file", "", "The name of the file that contains the secret key.")
	cmdPodAgentD.Flags.StringVar(&rootBlessings, "root-blessings", "", "A comma-separated list of the root blessings to trust, base64-encoded VOM-encoded.")

	cmdline.HideGlobalFlagsExcept()
	cmdline.Main(cmdPodAgentD)
}

var cmdPodAgentD = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runPodAgentD),
	Name:   "pod_agentd",
	Short:  "Holds the principal of a kubernetes pod",
	Long: `
Command pod_agentd runs a security agent daemon, which holds a private key in
memory and makes it available to the kubernetes pod in which it is running.
`,
}

func runPodAgentD(ctx *context.T, env *cmdline.Env, args []string) error {
	p, err := lsecurity.NewPrincipal()
	if err != nil {
		return err
	}
	if ctx, err = v23.WithPrincipal(ctx, p); err != nil {
		return err
	}
	if rootBlessings != "" {
		addRoot(ctx, rootBlessings)
	}

	secret, err := ioutil.ReadFile(secretKeyFile)
	if err != nil {
		return err
	}

	// Fetch blessings from cluster agent.
	ca := cluster.ClusterAgentClient(clusterAgent)
	blessings, err := ca.SeekBlessings(ctx, string(secret))
	if err != nil {
		return err
	}
	if err = p.BlessingStore().SetDefault(blessings); err != nil {
		return err
	}
	if _, err = p.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
		return err
	}
	if err = p.AddToRoots(blessings); err != nil {
		return err
	}

	// Run the server.
	i := ipc.NewIPC()
	defer i.Close()
	if err = server.ServeAgent(i, lsecurity.NewImmutablePrincipal(p)); err != nil {
		return err
	}
	if err = i.Listen(socketPath); err != nil {
		return err
	}
	<-signals.ShutdownOnSignals(ctx)
	return nil
}

func addRoot(ctx *context.T, flagRoots string) {
	p := v23.GetPrincipal(ctx)
	for _, b64 := range strings.Split(flagRoots, ",") {
		// We use URLEncoding to be compatible with the principal
		// command.
		vomBlessings, err := base64.URLEncoding.DecodeString(b64)
		if err != nil {
			ctx.Fatalf("unable to decode the base64 blessing roots: %v", err)
		}
		var blessings security.Blessings
		if err := vom.Decode(vomBlessings, &blessings); err != nil {
			ctx.Fatalf("unable to decode the vom blessing roots: %v", err)
		}
		if err := p.AddToRoots(blessings); err != nil {
			ctx.Fatalf("unable to add blessing roots: %v", err)
		}
	}
}
