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

package main

import (
	"fmt"
	"io"
	"regexp"
	"strings"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/options"
	"v.io/v23/rpc"
	"v.io/v23/rpc/reserved"
	"v.io/v23/security"
	"v.io/v23/vdl"
	"v.io/v23/vdlroot/signature"
	"v.io/x/lib/cmdline"
	"v.io/x/ref/lib/v23cmd"
	"v.io/x/ref/lib/vdl/build"
	"v.io/x/ref/lib/vdl/codegen/vdlgen"
	"v.io/x/ref/lib/vdl/compile"

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

var (
	flagInsecure       bool
	flagShowReserved   bool
	flagShallowResolve bool
	insecureOpts       = []rpc.CallOpt{
		options.ServerAuthorizer{security.AllowEveryone()},
		options.NameResolutionAuthorizer{security.AllowEveryone()},
	}
)

func main() {
	cmdline.HideGlobalFlagsExcept(regexp.MustCompile(`^v23\.namespace\.root$`))
	cmdline.Main(cmdVRPC)
}

func init() {
	const (
		insecureVal  = false
		insecureName = "insecure"
		insecureDesc = "If true, skip server authentication. This means that the client will reveal its blessings to servers that it may not recognize."
	)
	cmdSignature.Flags.BoolVar(&flagInsecure, insecureName, insecureVal, insecureDesc)
	cmdIdentify.Flags.BoolVar(&flagInsecure, insecureName, insecureVal, insecureDesc)

	cmdSignature.Flags.BoolVar(&flagShowReserved, "show-reserved", false, "if true, also show the signatures of reserved methods")
	cmdVRPC.Flags.BoolVar(&flagShallowResolve, "s", false, "if true, perform a shallow resolve")
}

var cmdVRPC = &cmdline.Command{
	Name:  "vrpc",
	Short: "sends and receives Vanadium remote procedure calls",
	Long: `
Command vrpc sends and receives Vanadium remote procedure calls.  It is used as
a generic client to interact with any Vanadium server.
`,
	// TODO(toddw): Add cmdServe, which will take an interface as input, and set
	// up a server capable of handling the given methods.  When a request is
	// received, it'll allow the user to respond via stdin.
	Children: []*cmdline.Command{cmdSignature, cmdCall, cmdIdentify},
}

const serverDesc = `
<server> identifies a Vanadium server.  It can either be the object address of
the server, or an object name that will be resolved to an end-point.
`

var cmdSignature = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runSignature),
	Name:   "signature",
	Short:  "Describe the interfaces of a Vanadium server",
	Long: `
Signature connects to the Vanadium server identified by <server>.

If no [method] is provided, returns all interfaces implemented by the server.

If a [method] is provided, returns the signature of just that method.
`,
	ArgsName: "<server> [method]",
	ArgsLong: serverDesc + `
[method] is the optional server method name.
`,
}

var cmdCall = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runCall),
	Name:   "call",
	Short:  "Call a method of a Vanadium server",
	Long: `
Call connects to the Vanadium server identified by <server> and calls the
<method> with the given positional [args...], returning results on stdout.

TODO(toddw): stdin is read for streaming arguments sent to the server.  An EOF
on stdin (e.g. via ^D) causes the send stream to be closed.

Regardless of whether the call is streaming, the main goroutine blocks for
streaming and positional results received from the server.

All input arguments (both positional and streaming) are specified as VDL
expressions, with commas separating multiple expressions.  Positional arguments
may also be specified as separate command-line arguments.  Streaming arguments
may also be specified as separate newline-terminated expressions.

The method signature is always retrieved from the server as a first step.  This
makes it easier to input complex typed arguments, since the top-level type for
each argument is implicit and doesn't need to be specified.
`,
	ArgsName: "<server> <method> [args...]",
	ArgsLong: serverDesc + `
<method> is the server method to call.

[args...] are the positional input arguments, specified as VDL expressions.
`,
}

var cmdIdentify = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runIdentify),
	Name:   "identify",
	Short:  "Reveal blessings presented by a Vanadium server",
	Long: `
Identify connects to the Vanadium server identified by <server> and dumps out
the blessings presented by that server (and the subset of those that are
considered valid by the principal running this tool) to standard output.
`,
	ArgsName: "<server>",
	ArgsLong: serverDesc,
}

func getNamespaceOpts(opts []rpc.CallOpt) []naming.NamespaceOpt {
	var out []naming.NamespaceOpt
	for _, o := range opts {
		if co, ok := o.(naming.NamespaceOpt); ok {
			out = append(out, co)
		}
	}
	return out
}

func rpcOpts(ctx *context.T, server string) ([]rpc.CallOpt, error) {
	var opts []rpc.CallOpt
	if flagInsecure {
		// Note that this flag is only settable on signature and
		// identify, as per ashankar@.
		opts = append(opts, insecureOpts...)
	}
	if flagShallowResolve {
		// Find the containing mount table.
		me, err := v23.GetNamespace(ctx).ShallowResolve(ctx, server, getNamespaceOpts(opts)...)
		if err != nil {
			return nil, err
		}
		opts = append(opts, options.Preresolved{me})
	}
	return opts, nil
}

func runSignature(ctx *context.T, env *cmdline.Env, args []string) error {
	// Error-check args.
	var server, method string
	switch len(args) {
	case 1:
		server = args[0]
	case 2:
		server, method = args[0], args[1]
	default:
		return env.UsageErrorf("wrong number of arguments")
	}
	// Get the interface or method signature, and pretty-print.  We print the
	// named types after the signatures, to aid in readability.
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	var types vdlgen.NamedTypes
	opts, err := rpcOpts(ctx, server)
	if err != nil {
		return err
	}
	if method != "" {
		methodSig, err := reserved.MethodSignature(ctx, server, method, opts...)
		if err != nil {
			return fmt.Errorf("MethodSignature failed: %v", err)
		}
		vdlgen.PrintMethod(env.Stdout, methodSig, &types)
		fmt.Fprintln(env.Stdout)
		types.Print(env.Stdout)
		return nil
	}
	ifacesSig, err := reserved.Signature(ctx, server, opts...)
	if err != nil {
		return fmt.Errorf("Signature failed: %v", err)
	}
	for i, iface := range ifacesSig {
		if !flagShowReserved && naming.IsReserved(iface.Name) {
			continue
		}
		if i > 0 {
			fmt.Fprintln(env.Stdout)
		}
		vdlgen.PrintInterface(env.Stdout, iface, &types)
		fmt.Fprintln(env.Stdout)
	}
	types.Print(env.Stdout)
	return nil
}

func runCall(ctx *context.T, env *cmdline.Env, args []string) error {
	// Error-check args, and set up argsdata with a comma-separated list of
	// arguments, allowing each individual arg to already be comma-separated.
	//
	// TODO(toddw): Should we just space-separate the args instead?
	if len(args) < 2 {
		return env.UsageErrorf("must specify <server> and <method>")
	}
	server, method := args[0], args[1]
	var argsdata string
	for _, arg := range args[2:] {
		arg := strings.TrimSpace(arg)
		if argsdata == "" || strings.HasSuffix(argsdata, ",") || strings.HasPrefix(arg, ",") {
			argsdata += arg
		} else {
			argsdata += "," + arg
		}
	}
	opts, err := rpcOpts(ctx, server)
	if err != nil {
		return err
	}
	// Get the method signature and parse args.
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	methodSig, err := reserved.MethodSignature(ctx, server, method, opts...)
	if err != nil {
		return fmt.Errorf("MethodSignature failed: %v", err)
	}
	inargs, err := parseInArgs(argsdata, methodSig)
	if err != nil {
		// TODO: Print signature and example.
		return err
	}
	// Start the method call.
	call, err := v23.GetClient(ctx).StartCall(ctx, server, method, inargs, opts...)
	if err != nil {
		return fmt.Errorf("StartCall failed: %v", err)
	}
	// TODO(toddw): Fire off a goroutine to handle streaming inputs.
	// Handle streaming results.
StreamingResultsLoop:
	for {
		var item *vdl.Value
		switch err := call.Recv(&item); {
		case err == io.EOF:
			break StreamingResultsLoop
		case err != nil:
			return fmt.Errorf("call.Recv failed: %v", err)
		}
		fmt.Fprintf(env.Stdout, "<< %v\n", vdlgen.TypedConst(item, "", nil))
	}
	// Finish the method call.
	outargs := make([]*vdl.Value, len(methodSig.OutArgs))
	outptrs := make([]interface{}, len(outargs))
	for i := range outargs {
		outptrs[i] = &outargs[i]
	}
	if err := call.Finish(outptrs...); err != nil {
		return fmt.Errorf("call.Finish failed: %v", err)
	}
	// Pretty-print results.
	for i, arg := range outargs {
		if i > 0 {
			fmt.Fprint(env.Stdout, " ")
		}
		fmt.Fprint(env.Stdout, vdlgen.TypedConst(arg, "", nil))
	}
	fmt.Fprintln(env.Stdout)
	return nil
}

func parseInArgs(argsdata string, methodSig signature.Method) ([]interface{}, error) {
	if len(methodSig.InArgs) == 0 {
		return nil, nil
	}
	var intypes []*vdl.Type
	for _, inarg := range methodSig.InArgs {
		intypes = append(intypes, inarg.Type)
	}
	env := compile.NewEnv(-1)
	inargs := build.BuildExprs(argsdata, intypes, env)
	if err := env.Errors.ToError(); err != nil {
		return nil, fmt.Errorf("can't parse in-args:\n%v", err)
	}
	if got, want := len(inargs), len(methodSig.InArgs); got != want {
		return nil, fmt.Errorf("got %d args, want %d", got, want)
	}
	// Translate []*vdl.Value to []interface, with each item still *vdl.Value.
	var ret []interface{}
	for _, arg := range inargs {
		ret = append(ret, arg)
	}
	return ret, nil
}

func runIdentify(ctx *context.T, env *cmdline.Env, args []string) error {
	if len(args) != 1 {
		return env.UsageErrorf("wrong number of arguments")
	}
	server := args[0]
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	opts, err := rpcOpts(ctx, server)
	if err != nil {
		return err
	}
	// The method name does not matter - only interested in authentication,
	// not in actually making an RPC.
	call, err := v23.GetClient(ctx).StartCall(ctx, server, "", nil, opts...)
	if err != nil {
		return fmt.Errorf(`client.StartCall(%q, "", nil) failed with %v`, server, err)
	}
	valid, presented := call.RemoteBlessings()
	fmt.Fprintf(env.Stdout, "PRESENTED: %v\nVALID:     %v\nPUBLICKEY: %v\n", presented, valid, presented.PublicKey())
	return nil
}
