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"
	"veyron2/vom"
	"veyron2/wiretype"

	idl_build "veyron2/services/mgmt/build"
	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 a Veyron 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_build.BinaryDescription
	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 []vdl.Any, tid wiretype.TypeID) string {
	var wt vdl.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 []vdl.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()
}
