package impl

import (
	"bytes"
	"fmt"
	"io"

	"veyron/lib/cmdline"
	idl_test_base "veyron/tools/vrpc/test_base"

	"veyron2"
	"veyron2/context"
	"veyron2/ipc"
	"veyron2/rt"
	"veyron2/vdl/vdlutil"
	"veyron2/vom"
	"veyron2/wiretype"

	idl_binary "veyron2/services/mgmt/binary"
	idl_node "veyron2/services/mgmt/node"
	idl_mounttable "veyron2/services/mounttable"
)

const serverDesc = `
<server> identifies the Veyron RPC server. It can either be the object address of
the server or an Object name in which case the vrpc will use Veyron's name
resolution to match this name to an end-point.
`
const methodDesc = `
<method> identifies the name of the method to be invoked.
`
const argsDesc = `
<args> identifies the arguments of the method to be invoked. It should be a list
of values in a VOM JSON format that can be reflected to the correct type
using Go's reflection.
`

var cmdDescribe = &cmdline.Command{
	Run:   runDescribe,
	Name:  "describe",
	Short: "Describe the API of an Veyron RPC server",
	Long: `
Describe connects to the Veyron RPC server identified by <server>, finds out what
its API is, and outputs a succint summary of this API to the standard output.
`,
	ArgsName: "<server>",
	ArgsLong: serverDesc,
}

func runDescribe(cmd *cmdline.Command, args []string) error {
	if len(args) != 1 {
		return cmd.Errorf("describe: incorrect number of arguments, expected 1, got %d", len(args))
	}

	runtime := rt.R()

	client, err := setupClient(cmd, runtime)
	if err != nil {
		return err
	}
	defer client.Close()

	ctx := runtime.NewContext()
	signature, err := getSignature(ctx, cmd, args[0], client)
	if err != nil {
		return err
	}

	for methodName, methodSignature := range signature.Methods {
		fmt.Fprintf(cmd.Stdout(), "%s\n", formatSignature(methodName, methodSignature, signature.TypeDefs))
	}
	return nil
}

var cmdInvoke = &cmdline.Command{
	Run:   runInvoke,
	Name:  "invoke",
	Short: "Invoke a method of an Veyron RPC server",
	Long: `
Invoke connects to the Veyron RPC server identified by <server>, invokes the method
identified by <method>, supplying the arguments identified by <args>, and outputs
the results of the invocation to the standard output.
`,
	ArgsName: "<server> <method> <args>",
	ArgsLong: serverDesc + methodDesc + argsDesc,
}

func runInvoke(cmd *cmdline.Command, args []string) error {
	if len(args) < 2 {
		return cmd.Errorf("invoke: incorrect number of arguments, expected at least 2, got %d", len(args))
	}
	server, method, args := args[0], args[1], args[2:]

	runtime := rt.R()

	client, err := setupClient(cmd, runtime)
	if err != nil {
		return err
	}
	defer client.Close()

	ctx := runtime.NewContext()
	signature, err := getSignature(ctx, cmd, server, client)
	if err != nil {
		return fmt.Errorf("invoke: failed to get signature for %v: %v", server, err)
	}
	if len(signature.Methods) == 0 {
		return fmt.Errorf("invoke: empty signature for %v", server)
	}

	methodSignature, found := signature.Methods[method]
	if !found {
		return fmt.Errorf("invoke: method %s not found", method)
	}

	if len(args) != len(methodSignature.InArgs) {
		return cmd.Errorf("invoke: incorrect number of arguments, expected %d, got %d", len(methodSignature.InArgs), len(args))
	}

	// Register all user-defined types you would like to use.
	//
	// TODO(jsimsa): This is a temporary hack to get vrpc to work. When
	// Benj implements support for decoding arbitrary structs to an
	// empty interface, this will no longer be needed.
	var x1 idl_test_base.Struct
	vom.Register(x1)
	var x2 idl_node.Description
	vom.Register(x2)
	var x3 idl_binary.Description
	vom.Register(x3)
	var x4 idl_mounttable.MountedServer
	vom.Register(x4)
	var x5 idl_mounttable.MountEntry
	vom.Register(x5)

	// Decode the inputs from vomJSON-formatted command-line arguments.
	inputs := make([]interface{}, len(args))
	for i := range args {
		var buf bytes.Buffer
		buf.WriteString(args[i])
		buf.WriteByte(0)
		decoder := vom.NewDecoder(&buf)
		if err := decoder.Decode(&inputs[i]); err != nil {
			return fmt.Errorf("decoder.Decode() failed for %s with %v", args[i], err)
		}
	}

	// Initiate the method invocation.
	call, err := client.StartCall(ctx, server, method, inputs)
	if err != nil {
		return fmt.Errorf("client.StartCall(%s, %q, %v) failed with %v", server, method, inputs, err)
	}

	fmt.Fprintf(cmd.Stdout(), "%s = ", formatInput(method, inputs))

	// Handle streaming results, if the method happens to be streaming.
	var item interface{}
	nStream := 0
forloop:
	for ; ; nStream++ {
		switch err := call.Recv(&item); err {
		case io.EOF:
			break forloop
		case nil:
			if nStream == 0 {
				fmt.Fprintln(cmd.Stdout(), "<<")
			}
			fmt.Fprintf(cmd.Stdout(), "%d: %v\n", nStream, item)
		default:
			return fmt.Errorf("call.Recv failed with %v", err)
		}
	}
	if nStream > 0 {
		fmt.Fprintf(cmd.Stdout(), ">> ")
	}

	// Receive the outputs of the method invocation.
	outputs := make([]interface{}, len(methodSignature.OutArgs))
	outputPtrs := make([]interface{}, len(methodSignature.OutArgs))
	for i := range outputs {
		outputPtrs[i] = &outputs[i]
	}
	if err := call.Finish(outputPtrs...); err != nil {
		return fmt.Errorf("call.Finish() failed with %v", err)
	}
	fmt.Fprintf(cmd.Stdout(), "%s\n", formatOutput(outputs))

	return nil
}

// Root returns the root command for the vrpc tool.
func Root() *cmdline.Command {
	return &cmdline.Command{
		Name:  "vrpc",
		Short: "Command-line tool for interacting with Veyron RPC servers.",
		Long: `
The vrpc tool enables interacting with Veyron RPC servers. In particular,
it can be used to 1) find out what API a Veyron RPC server exports and
2) send requests to a Veyron RPC server.
`,
		Children: []*cmdline.Command{cmdDescribe, cmdInvoke},
	}
}

func setupClient(cmd *cmdline.Command, r veyron2.Runtime) (ipc.Client, error) {
	client, err := r.NewClient()
	if err != nil {
		return nil, fmt.Errorf("NewClient failed: %v", err)
	}
	return client, nil
}

func getSignature(ctx context.T, cmd *cmdline.Command, server string, client ipc.Client) (ipc.ServiceSignature, error) {
	call, err := client.StartCall(ctx, server, "Signature", nil)
	if err != nil {
		return ipc.ServiceSignature{}, fmt.Errorf("client.StartCall(%s, Signature, nil) failed with %v", server, err)
	}
	var signature ipc.ServiceSignature
	var sigerr error
	if err = call.Finish(&signature, &sigerr); err != nil {
		return ipc.ServiceSignature{}, fmt.Errorf("client.Finish(&signature, &sigerr) failed with %v", err)
	}
	return signature, sigerr
}

// formatWiretype generates a string representation of the specified type.
func formatWiretype(td []vdlutil.Any, tid wiretype.TypeID) string {
	var wt vdlutil.Any
	if tid >= wiretype.TypeIDFirst {
		wt = td[tid-wiretype.TypeIDFirst]
	} else {
		for _, pair := range wiretype.BootstrapTypes {
			if pair.TID == tid {
				wt = pair.WT
			}
		}
		if wt == nil {
			return fmt.Sprintf("UNKNOWN_TYPE[%v]", tid)
		}
	}

	switch t := wt.(type) {
	case wiretype.NamedPrimitiveType:
		if t.Name != "" {
			return t.Name
		}
		return tid.Name()
	case wiretype.SliceType:
		return fmt.Sprintf("[]%s", formatWiretype(td, t.Elem))
	case wiretype.ArrayType:
		return fmt.Sprintf("[%d]%s", t.Len, formatWiretype(td, t.Elem))
	case wiretype.MapType:
		return fmt.Sprintf("map[%s]%s", formatWiretype(td, t.Key), formatWiretype(td, t.Elem))
	case wiretype.StructType:
		var buf bytes.Buffer
		buf.WriteString("struct{")
		for i, fld := range t.Fields {
			if i > 0 {
				buf.WriteString(", ")
			}
			buf.WriteString(fld.Name)
			buf.WriteString(" ")
			buf.WriteString(formatWiretype(td, fld.Type))
		}
		buf.WriteString("}")
		return buf.String()
	default:
		panic(fmt.Sprintf("unknown writetype: %T", wt))
	}
}

func formatSignature(name string, ms ipc.MethodSignature, defs []vdlutil.Any) string {
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "func %s(", name)
	for index, arg := range ms.InArgs {
		if index > 0 {
			buf.WriteString(", ")
		}
		fmt.Fprintf(&buf, "%s %s", arg.Name, formatWiretype(defs, arg.Type))
	}
	buf.WriteString(") ")
	if ms.InStream != wiretype.TypeIDInvalid || ms.OutStream != wiretype.TypeIDInvalid {
		buf.WriteString("stream<")
		if ms.InStream == wiretype.TypeIDInvalid {
			buf.WriteString("_")
		} else {
			fmt.Fprintf(&buf, "%s", formatWiretype(defs, ms.InStream))
		}
		buf.WriteString(", ")
		if ms.OutStream == wiretype.TypeIDInvalid {
			buf.WriteString("_")
		} else {
			fmt.Fprintf(&buf, "%s", formatWiretype(defs, ms.OutStream))
		}
		buf.WriteString("> ")
	}
	buf.WriteString("(")
	for index, arg := range ms.OutArgs {
		if index > 0 {
			buf.WriteString(", ")
		}
		if arg.Name != "" {
			fmt.Fprintf(&buf, "%s ", arg.Name)
		}
		fmt.Fprintf(&buf, "%s", formatWiretype(defs, arg.Type))
	}
	buf.WriteString(")")
	return buf.String()
}

func formatInput(name string, inputs []interface{}) string {
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "%s(", name)
	for index, value := range inputs {
		if index > 0 {
			buf.WriteString(", ")
		}
		fmt.Fprintf(&buf, "%v", value)
	}
	buf.WriteString(")")
	return buf.String()
}

func formatOutput(outputs []interface{}) string {
	var buf bytes.Buffer
	buf.WriteString("[")
	for index, value := range outputs {
		if index > 0 {
			buf.WriteString(", ")
		}
		fmt.Fprintf(&buf, "%v", value)
	}
	buf.WriteString("]")
	return buf.String()
}
