// This file was auto-generated by the veyron vdl tool.
// Source: debug.vdl

package debug

import (
	"veyron.io/veyron/veyron2/services/mgmt/logreader"

	"veyron.io/veyron/veyron2/services/mgmt/pprof"

	"veyron.io/veyron/veyron2/services/mgmt/stats"

	// The non-user imports are prefixed with "__" to prevent collisions.
	__veyron2 "veyron.io/veyron/veyron2"
	__context "veyron.io/veyron/veyron2/context"
	__ipc "veyron.io/veyron/veyron2/ipc"
	__vdlutil "veyron.io/veyron/veyron2/vdl/vdlutil"
	__wiretype "veyron.io/veyron/veyron2/wiretype"
)

// TODO(toddw): Remove this line once the new signature support is done.
// It corrects a bug where __wiretype is unused in VDL pacakges where only
// bootstrap types are used on interfaces.
const _ = __wiretype.TypeIDInvalid

// DebugClientMethods is the client interface
// containing Debug methods.
//
// 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 DebugClientMethods interface {
	// LogFile can be used to access log files remotely.
	logreader.LogFileClientMethods
	// 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.StatsClientMethods
	pprof.PProfClientMethods
}

// DebugClientStub adds universal methods to DebugClientMethods.
type DebugClientStub interface {
	DebugClientMethods
	__ipc.UniversalServiceMethods
}

// DebugClient returns a client stub for Debug.
func DebugClient(name string, opts ...__ipc.BindOpt) DebugClientStub {
	var client __ipc.Client
	for _, opt := range opts {
		if clientOpt, ok := opt.(__ipc.Client); ok {
			client = clientOpt
		}
	}
	return implDebugClientStub{name, client, logreader.LogFileClient(name, client), stats.StatsClient(name, client), pprof.PProfClient(name, client)}
}

type implDebugClientStub struct {
	name   string
	client __ipc.Client

	logreader.LogFileClientStub
	stats.StatsClientStub
	pprof.PProfClientStub
}

func (c implDebugClientStub) c(ctx __context.T) __ipc.Client {
	if c.client != nil {
		return c.client
	}
	return __veyron2.RuntimeFromContext(ctx).Client()
}

func (c implDebugClientStub) Signature(ctx __context.T, opts ...__ipc.CallOpt) (o0 __ipc.ServiceSignature, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Signature", nil, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

func (c implDebugClientStub) GetMethodTags(ctx __context.T, method string, opts ...__ipc.CallOpt) (o0 []interface{}, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

// DebugServerMethods is the interface a server writer
// implements for Debug.
//
// 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 DebugServerMethods interface {
	// LogFile can be used to access log files remotely.
	logreader.LogFileServerMethods
	// 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.StatsServerMethods
	pprof.PProfServerMethods
}

// DebugServerStubMethods is the server interface containing
// Debug methods, as expected by ipc.Server.  The difference between
// this interface and DebugServerMethods is that the first context
// argument for each method is always ipc.ServerCall here, while it is either
// ipc.ServerContext or a typed streaming context there.
type DebugServerStubMethods interface {
	// LogFile can be used to access log files remotely.
	logreader.LogFileServerStubMethods
	// 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.StatsServerStubMethods
	pprof.PProfServerStubMethods
}

// DebugServerStub adds universal methods to DebugServerStubMethods.
type DebugServerStub interface {
	DebugServerStubMethods
	// GetMethodTags will be replaced with DescribeInterfaces.
	GetMethodTags(call __ipc.ServerCall, method string) ([]interface{}, error)
	// Signature will be replaced with DescribeInterfaces.
	Signature(call __ipc.ServerCall) (__ipc.ServiceSignature, error)
}

// DebugServer returns a server stub for Debug.
// It converts an implementation of DebugServerMethods into
// an object that may be used by ipc.Server.
func DebugServer(impl DebugServerMethods) DebugServerStub {
	stub := implDebugServerStub{
		impl:              impl,
		LogFileServerStub: logreader.LogFileServer(impl),
		StatsServerStub:   stats.StatsServer(impl),
		PProfServerStub:   pprof.PProfServer(impl),
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := __ipc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := __ipc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implDebugServerStub struct {
	impl DebugServerMethods
	gs   *__ipc.GlobState

	logreader.LogFileServerStub
	stats.StatsServerStub
	pprof.PProfServerStub
}

func (s implDebugServerStub) VGlob() *__ipc.GlobState {
	return s.gs
}

func (s implDebugServerStub) GetMethodTags(call __ipc.ServerCall, method string) ([]interface{}, error) {
	// TODO(toddw): Replace with new DescribeInterfaces implementation.
	if resp, err := s.LogFileServerStub.GetMethodTags(call, method); resp != nil || err != nil {
		return resp, err
	}
	if resp, err := s.StatsServerStub.GetMethodTags(call, method); resp != nil || err != nil {
		return resp, err
	}
	if resp, err := s.PProfServerStub.GetMethodTags(call, method); resp != nil || err != nil {
		return resp, err
	}
	return nil, nil
}

func (s implDebugServerStub) Signature(call __ipc.ServerCall) (__ipc.ServiceSignature, error) {
	// TODO(toddw) Replace with new DescribeInterfaces implementation.
	result := __ipc.ServiceSignature{Methods: make(map[string]__ipc.MethodSignature)}

	result.TypeDefs = []__vdlutil.Any{}
	var ss __ipc.ServiceSignature
	var firstAdded int
	ss, _ = s.LogFileServerStub.Signature(call)
	firstAdded = len(result.TypeDefs)
	for k, v := range ss.Methods {
		for i, _ := range v.InArgs {
			if v.InArgs[i].Type >= __wiretype.TypeIDFirst {
				v.InArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		for i, _ := range v.OutArgs {
			if v.OutArgs[i].Type >= __wiretype.TypeIDFirst {
				v.OutArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		if v.InStream >= __wiretype.TypeIDFirst {
			v.InStream += __wiretype.TypeID(firstAdded)
		}
		if v.OutStream >= __wiretype.TypeIDFirst {
			v.OutStream += __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 __wiretype.SliceType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.ArrayType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.MapType:
			if wt.Key >= __wiretype.TypeIDFirst {
				wt.Key += __wiretype.TypeID(firstAdded)
			}
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.StructType:
			for i, fld := range wt.Fields {
				if fld.Type >= __wiretype.TypeIDFirst {
					wt.Fields[i].Type += __wiretype.TypeID(firstAdded)
				}
			}
			d = wt
			// NOTE: other types are missing, but we are upgrading anyways.
		}
		result.TypeDefs = append(result.TypeDefs, d)
	}
	ss, _ = s.StatsServerStub.Signature(call)
	firstAdded = len(result.TypeDefs)
	for k, v := range ss.Methods {
		for i, _ := range v.InArgs {
			if v.InArgs[i].Type >= __wiretype.TypeIDFirst {
				v.InArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		for i, _ := range v.OutArgs {
			if v.OutArgs[i].Type >= __wiretype.TypeIDFirst {
				v.OutArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		if v.InStream >= __wiretype.TypeIDFirst {
			v.InStream += __wiretype.TypeID(firstAdded)
		}
		if v.OutStream >= __wiretype.TypeIDFirst {
			v.OutStream += __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 __wiretype.SliceType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.ArrayType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.MapType:
			if wt.Key >= __wiretype.TypeIDFirst {
				wt.Key += __wiretype.TypeID(firstAdded)
			}
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.StructType:
			for i, fld := range wt.Fields {
				if fld.Type >= __wiretype.TypeIDFirst {
					wt.Fields[i].Type += __wiretype.TypeID(firstAdded)
				}
			}
			d = wt
			// NOTE: other types are missing, but we are upgrading anyways.
		}
		result.TypeDefs = append(result.TypeDefs, d)
	}
	ss, _ = s.PProfServerStub.Signature(call)
	firstAdded = len(result.TypeDefs)
	for k, v := range ss.Methods {
		for i, _ := range v.InArgs {
			if v.InArgs[i].Type >= __wiretype.TypeIDFirst {
				v.InArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		for i, _ := range v.OutArgs {
			if v.OutArgs[i].Type >= __wiretype.TypeIDFirst {
				v.OutArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		if v.InStream >= __wiretype.TypeIDFirst {
			v.InStream += __wiretype.TypeID(firstAdded)
		}
		if v.OutStream >= __wiretype.TypeIDFirst {
			v.OutStream += __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 __wiretype.SliceType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.ArrayType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.MapType:
			if wt.Key >= __wiretype.TypeIDFirst {
				wt.Key += __wiretype.TypeID(firstAdded)
			}
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.StructType:
			for i, fld := range wt.Fields {
				if fld.Type >= __wiretype.TypeIDFirst {
					wt.Fields[i].Type += __wiretype.TypeID(firstAdded)
				}
			}
			d = wt
			// NOTE: other types are missing, but we are upgrading anyways.
		}
		result.TypeDefs = append(result.TypeDefs, d)
	}

	return result, nil
}
