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

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")
}

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 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
	var opts []rpc.CallOpt
	if flagInsecure {
		opts = append(opts, options.SkipServerEndpointAuthorization{})
	}
	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
		}
	}
	// Get the method signature and parse args.
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	methodSig, err := reserved.MethodSignature(ctx, server, method)
	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)
	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()
	var opts []rpc.CallOpt
	if flagInsecure {
		opts = append(opts, options.SkipServerEndpointAuthorization{})
	}
	// 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
}
