veyron/services/mgmt/logreader/impl: Add Signature hack

This is a temporary hack that adds a Signature invoker until
https://code.google.com/p/envyor/issues/detail?id=285 is resolved.

Change-Id: Ib0a98a474630dc1b8a900712e665e622349bfe16
diff --git a/services/mgmt/debug/debug.vdl b/services/mgmt/debug/debug.vdl
new file mode 100644
index 0000000..fe70a6d
--- /dev/null
+++ b/services/mgmt/debug/debug.vdl
@@ -0,0 +1,15 @@
+package debug
+
+import (
+	"veyron2/services/mgmt/logreader"
+	"veyron2/services/mgmt/stats"
+)
+
+// This interface exists only for the purpose of generating a valid Signature
+// for all the interfaces that are served by the debug server. It should be
+// removed when https://code.google.com/p/envyor/issues/detail?id=285 is
+// resolved.
+type Debug interface {
+	logreader.LogFile
+	stats.Stats
+}
diff --git a/services/mgmt/debug/debug.vdl.go b/services/mgmt/debug/debug.vdl.go
new file mode 100644
index 0000000..a2cb249
--- /dev/null
+++ b/services/mgmt/debug/debug.vdl.go
@@ -0,0 +1,305 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: debug.vdl
+
+package debug
+
+import (
+	"veyron2/services/mgmt/logreader"
+
+	"veyron2/services/mgmt/stats"
+
+	// The non-user imports are prefixed with "_gen_" to prevent collisions.
+	_gen_veyron2 "veyron2"
+	_gen_context "veyron2/context"
+	_gen_ipc "veyron2/ipc"
+	_gen_naming "veyron2/naming"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
+	_gen_wiretype "veyron2/wiretype"
+)
+
+// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+const _ = _gen_wiretype.TypeIDInvalid
+
+// This interface exists only for the purpose of generating a valid Signature
+// for all the interfaces that are served by the debug server. It should be
+// removed when https://code.google.com/p/envyor/issues/detail?id=285 is
+// resolved.
+// Debug is the interface the client binds and uses.
+// Debug_ExcludingUniversal is the interface without internal framework-added methods
+// to enable embedding without method collisions.  Not to be used directly by clients.
+type Debug_ExcludingUniversal interface {
+	// LogFile can be used to access log files remotely.
+	logreader.LogFile_ExcludingUniversal
+	// The Stats interface is used to access stats for troubleshooting and
+	// monitoring purposes. The stats objects are discoverable via the Globbable
+	// interface and watchable via the GlobWatcher interface.
+	//
+	// The types of the object values are implementation specific, but should be
+	// primarily numeric in nature, e.g. counters, memory usage, latency metrics,
+	// etc.
+	stats.Stats_ExcludingUniversal
+}
+type Debug interface {
+	_gen_ipc.UniversalServiceMethods
+	Debug_ExcludingUniversal
+}
+
+// DebugService is the interface the server implements.
+type DebugService interface {
+
+	// LogFile can be used to access log files remotely.
+	logreader.LogFileService
+	// The Stats interface is used to access stats for troubleshooting and
+	// monitoring purposes. The stats objects are discoverable via the Globbable
+	// interface and watchable via the GlobWatcher interface.
+	//
+	// The types of the object values are implementation specific, but should be
+	// primarily numeric in nature, e.g. counters, memory usage, latency metrics,
+	// etc.
+	stats.StatsService
+}
+
+// BindDebug returns the client stub implementing the Debug
+// interface.
+//
+// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
+// global Runtime is used.
+func BindDebug(name string, opts ..._gen_ipc.BindOpt) (Debug, error) {
+	var client _gen_ipc.Client
+	switch len(opts) {
+	case 0:
+		// Do nothing.
+	case 1:
+		if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
+			client = clientOpt
+		} else {
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
+		}
+	default:
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
+	}
+	stub := &clientStubDebug{defaultClient: client, name: name}
+	stub.LogFile_ExcludingUniversal, _ = logreader.BindLogFile(name, client)
+	stub.Stats_ExcludingUniversal, _ = stats.BindStats(name, client)
+
+	return stub, nil
+}
+
+// NewServerDebug creates a new server stub.
+//
+// It takes a regular server implementing the DebugService
+// interface, and returns a new server stub.
+func NewServerDebug(server DebugService) interface{} {
+	return &ServerStubDebug{
+		ServerStubLogFile: *logreader.NewServerLogFile(server).(*logreader.ServerStubLogFile),
+		ServerStubStats:   *stats.NewServerStats(server).(*stats.ServerStubStats),
+		service:           server,
+	}
+}
+
+// clientStubDebug implements Debug.
+type clientStubDebug struct {
+	logreader.LogFile_ExcludingUniversal
+	stats.Stats_ExcludingUniversal
+
+	defaultClient _gen_ipc.Client
+	name          string
+}
+
+func (__gen_c *clientStubDebug) client(ctx _gen_context.T) _gen_ipc.Client {
+	if __gen_c.defaultClient != nil {
+		return __gen_c.defaultClient
+	}
+	return _gen_veyron2.RuntimeFromContext(ctx).Client()
+}
+
+func (__gen_c *clientStubDebug) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubDebug) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubDebug) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+// ServerStubDebug wraps a server that implements
+// DebugService and provides an object that satisfies
+// the requirements of veyron2/ipc.ReflectInvoker.
+type ServerStubDebug struct {
+	logreader.ServerStubLogFile
+	stats.ServerStubStats
+
+	service DebugService
+}
+
+func (__gen_s *ServerStubDebug) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
+	// TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
+	// Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
+	// This will change when it is replaced with Signature().
+	if resp, err := __gen_s.ServerStubLogFile.GetMethodTags(call, method); resp != nil || err != nil {
+		return resp, err
+	}
+	if resp, err := __gen_s.ServerStubStats.GetMethodTags(call, method); resp != nil || err != nil {
+		return resp, err
+	}
+	return nil, nil
+}
+
+func (__gen_s *ServerStubDebug) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
+	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
+
+	result.TypeDefs = []_gen_vdlutil.Any{}
+	var ss _gen_ipc.ServiceSignature
+	var firstAdded int
+	ss, _ = __gen_s.ServerStubLogFile.Signature(call)
+	firstAdded = len(result.TypeDefs)
+	for k, v := range ss.Methods {
+		for i, _ := range v.InArgs {
+			if v.InArgs[i].Type >= _gen_wiretype.TypeIDFirst {
+				v.InArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
+			}
+		}
+		for i, _ := range v.OutArgs {
+			if v.OutArgs[i].Type >= _gen_wiretype.TypeIDFirst {
+				v.OutArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
+			}
+		}
+		if v.InStream >= _gen_wiretype.TypeIDFirst {
+			v.InStream += _gen_wiretype.TypeID(firstAdded)
+		}
+		if v.OutStream >= _gen_wiretype.TypeIDFirst {
+			v.OutStream += _gen_wiretype.TypeID(firstAdded)
+		}
+		result.Methods[k] = v
+	}
+	//TODO(bprosnitz) combine type definitions from embeded interfaces in a way that doesn't cause duplication.
+	for _, d := range ss.TypeDefs {
+		switch wt := d.(type) {
+		case _gen_wiretype.SliceType:
+			if wt.Elem >= _gen_wiretype.TypeIDFirst {
+				wt.Elem += _gen_wiretype.TypeID(firstAdded)
+			}
+			d = wt
+		case _gen_wiretype.ArrayType:
+			if wt.Elem >= _gen_wiretype.TypeIDFirst {
+				wt.Elem += _gen_wiretype.TypeID(firstAdded)
+			}
+			d = wt
+		case _gen_wiretype.MapType:
+			if wt.Key >= _gen_wiretype.TypeIDFirst {
+				wt.Key += _gen_wiretype.TypeID(firstAdded)
+			}
+			if wt.Elem >= _gen_wiretype.TypeIDFirst {
+				wt.Elem += _gen_wiretype.TypeID(firstAdded)
+			}
+			d = wt
+		case _gen_wiretype.StructType:
+			for i, fld := range wt.Fields {
+				if fld.Type >= _gen_wiretype.TypeIDFirst {
+					wt.Fields[i].Type += _gen_wiretype.TypeID(firstAdded)
+				}
+			}
+			d = wt
+			// NOTE: other types are missing, but we are upgrading anyways.
+		}
+		result.TypeDefs = append(result.TypeDefs, d)
+	}
+	ss, _ = __gen_s.ServerStubStats.Signature(call)
+	firstAdded = len(result.TypeDefs)
+	for k, v := range ss.Methods {
+		for i, _ := range v.InArgs {
+			if v.InArgs[i].Type >= _gen_wiretype.TypeIDFirst {
+				v.InArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
+			}
+		}
+		for i, _ := range v.OutArgs {
+			if v.OutArgs[i].Type >= _gen_wiretype.TypeIDFirst {
+				v.OutArgs[i].Type += _gen_wiretype.TypeID(firstAdded)
+			}
+		}
+		if v.InStream >= _gen_wiretype.TypeIDFirst {
+			v.InStream += _gen_wiretype.TypeID(firstAdded)
+		}
+		if v.OutStream >= _gen_wiretype.TypeIDFirst {
+			v.OutStream += _gen_wiretype.TypeID(firstAdded)
+		}
+		result.Methods[k] = v
+	}
+	//TODO(bprosnitz) combine type definitions from embeded interfaces in a way that doesn't cause duplication.
+	for _, d := range ss.TypeDefs {
+		switch wt := d.(type) {
+		case _gen_wiretype.SliceType:
+			if wt.Elem >= _gen_wiretype.TypeIDFirst {
+				wt.Elem += _gen_wiretype.TypeID(firstAdded)
+			}
+			d = wt
+		case _gen_wiretype.ArrayType:
+			if wt.Elem >= _gen_wiretype.TypeIDFirst {
+				wt.Elem += _gen_wiretype.TypeID(firstAdded)
+			}
+			d = wt
+		case _gen_wiretype.MapType:
+			if wt.Key >= _gen_wiretype.TypeIDFirst {
+				wt.Key += _gen_wiretype.TypeID(firstAdded)
+			}
+			if wt.Elem >= _gen_wiretype.TypeIDFirst {
+				wt.Elem += _gen_wiretype.TypeID(firstAdded)
+			}
+			d = wt
+		case _gen_wiretype.StructType:
+			for i, fld := range wt.Fields {
+				if fld.Type >= _gen_wiretype.TypeIDFirst {
+					wt.Fields[i].Type += _gen_wiretype.TypeID(firstAdded)
+				}
+			}
+			d = wt
+			// NOTE: other types are missing, but we are upgrading anyways.
+		}
+		result.TypeDefs = append(result.TypeDefs, d)
+	}
+
+	return result, nil
+}
+
+func (__gen_s *ServerStubDebug) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
+	if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
+		return unresolver.UnresolveStep(call)
+	}
+	if call.Server() == nil {
+		return
+	}
+	var published []string
+	if published, err = call.Server().Published(); err != nil || published == nil {
+		return
+	}
+	reply = make([]string, len(published))
+	for i, p := range published {
+		reply[i] = _gen_naming.Join(p, call.Name())
+	}
+	return
+}
diff --git a/services/mgmt/debug/dispatcher.go b/services/mgmt/debug/dispatcher.go
index 43e7b41..71aa23e 100644
--- a/services/mgmt/debug/dispatcher.go
+++ b/services/mgmt/debug/dispatcher.go
@@ -28,6 +28,9 @@
 }
 
 func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+	if method == "Signature" {
+		return NewSignatureInvoker(suffix), d.auth, nil
+	}
 	if len(suffix) == 0 {
 		leaves := []string{"logs", "stats"}
 		return ipc.ReflectInvoker(&topLevelGlobInvoker{d.rt, leaves}), d.auth, nil
diff --git a/services/mgmt/debug/signature.go b/services/mgmt/debug/signature.go
new file mode 100644
index 0000000..9f3b33b
--- /dev/null
+++ b/services/mgmt/debug/signature.go
@@ -0,0 +1,37 @@
+package debug
+
+import (
+	"strings"
+
+	"veyron2/ipc"
+)
+
+type signatureInvoker struct {
+	suffix string
+}
+
+// NewSignatureInvoker is the invoker factory.
+func NewSignatureInvoker(suffix string) ipc.Invoker {
+	return ipc.ReflectInvoker(&signatureInvoker{suffix})
+}
+
+// TODO(rthellend): This is a temporary hack until https://code.google.com/p/envyor/issues/detail?id=285 is resolved.
+func (s signatureInvoker) Signature(ipc.ServerCall) (ipc.ServiceSignature, error) {
+	debugStub := ServerStubDebug{}
+	fullSig, _ := debugStub.Signature(nil)
+
+	var show []string
+	if strings.HasPrefix(s.suffix, "logs") {
+		show = []string{"ReadLog", "Size", "Glob"}
+	} else if strings.HasPrefix(s.suffix, "stats") {
+		show = []string{"Value", "Glob", "WatchGlob"}
+	} else {
+		show = []string{"Glob"}
+	}
+
+	sig := ipc.ServiceSignature{TypeDefs: fullSig.TypeDefs, Methods: make(map[string]ipc.MethodSignature)}
+	for _, m := range show {
+		sig.Methods[m] = fullSig.Methods[m]
+	}
+	return sig, nil
+}