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

// This file was auto-generated by the vanadium vdl tool.
// Source: sync.vdl

package vsync

import (
	// VDL system imports
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
)

// SyncClientMethods is the client interface
// containing Sync methods.
//
// Sync defines methods for data exchange between Syncbases.
// TODO(hpucha): Flesh this out further.
type SyncClientMethods interface {
	// GetDeltas returns the responder's current generation vector
	// and all the missing log records when compared to the
	// initiator's generation vector.
	GetDeltas(*context.T, ...rpc.CallOpt) error
	// CreateSyncGroup is typically invoked on a "central" peer to
	// request the creation of a SyncGroup.
	CreateSyncGroup(*context.T, ...rpc.CallOpt) error
	// JoinSyncGroup is invoked on a SyncGroup Admin and checks if
	// the requestor can join the SyncGroup.
	JoinSyncGroup(*context.T, ...rpc.CallOpt) error
	// BlobSync methods.
	// FetchBlob returns the requested blob.
	FetchBlob(*context.T, ...rpc.CallOpt) error
}

// SyncClientStub adds universal methods to SyncClientMethods.
type SyncClientStub interface {
	SyncClientMethods
	rpc.UniversalServiceMethods
}

// SyncClient returns a client stub for Sync.
func SyncClient(name string) SyncClientStub {
	return implSyncClientStub{name}
}

type implSyncClientStub struct {
	name string
}

func (c implSyncClientStub) GetDeltas(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "GetDeltas", nil, nil, opts...)
	return
}

func (c implSyncClientStub) CreateSyncGroup(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "CreateSyncGroup", nil, nil, opts...)
	return
}

func (c implSyncClientStub) JoinSyncGroup(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "JoinSyncGroup", nil, nil, opts...)
	return
}

func (c implSyncClientStub) FetchBlob(ctx *context.T, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "FetchBlob", nil, nil, opts...)
	return
}

// SyncServerMethods is the interface a server writer
// implements for Sync.
//
// Sync defines methods for data exchange between Syncbases.
// TODO(hpucha): Flesh this out further.
type SyncServerMethods interface {
	// GetDeltas returns the responder's current generation vector
	// and all the missing log records when compared to the
	// initiator's generation vector.
	GetDeltas(*context.T, rpc.ServerCall) error
	// CreateSyncGroup is typically invoked on a "central" peer to
	// request the creation of a SyncGroup.
	CreateSyncGroup(*context.T, rpc.ServerCall) error
	// JoinSyncGroup is invoked on a SyncGroup Admin and checks if
	// the requestor can join the SyncGroup.
	JoinSyncGroup(*context.T, rpc.ServerCall) error
	// BlobSync methods.
	// FetchBlob returns the requested blob.
	FetchBlob(*context.T, rpc.ServerCall) error
}

// SyncServerStubMethods is the server interface containing
// Sync methods, as expected by rpc.Server.
// There is no difference between this interface and SyncServerMethods
// since there are no streaming methods.
type SyncServerStubMethods SyncServerMethods

// SyncServerStub adds universal methods to SyncServerStubMethods.
type SyncServerStub interface {
	SyncServerStubMethods
	// Describe the Sync interfaces.
	Describe__() []rpc.InterfaceDesc
}

// SyncServer returns a server stub for Sync.
// It converts an implementation of SyncServerMethods into
// an object that may be used by rpc.Server.
func SyncServer(impl SyncServerMethods) SyncServerStub {
	stub := implSyncServerStub{
		impl: 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 := rpc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := rpc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implSyncServerStub struct {
	impl SyncServerMethods
	gs   *rpc.GlobState
}

func (s implSyncServerStub) GetDeltas(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.GetDeltas(ctx, call)
}

func (s implSyncServerStub) CreateSyncGroup(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.CreateSyncGroup(ctx, call)
}

func (s implSyncServerStub) JoinSyncGroup(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.JoinSyncGroup(ctx, call)
}

func (s implSyncServerStub) FetchBlob(ctx *context.T, call rpc.ServerCall) error {
	return s.impl.FetchBlob(ctx, call)
}

func (s implSyncServerStub) Globber() *rpc.GlobState {
	return s.gs
}

func (s implSyncServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{SyncDesc}
}

// SyncDesc describes the Sync interface.
var SyncDesc rpc.InterfaceDesc = descSync

// descSync hides the desc to keep godoc clean.
var descSync = rpc.InterfaceDesc{
	Name:    "Sync",
	PkgPath: "v.io/syncbase/x/ref/services/syncbase/vsync",
	Doc:     "// Sync defines methods for data exchange between Syncbases.\n// TODO(hpucha): Flesh this out further.",
	Methods: []rpc.MethodDesc{
		{
			Name: "GetDeltas",
			Doc:  "// GetDeltas returns the responder's current generation vector\n// and all the missing log records when compared to the\n// initiator's generation vector.",
		},
		{
			Name: "CreateSyncGroup",
			Doc:  "// CreateSyncGroup is typically invoked on a \"central\" peer to\n// request the creation of a SyncGroup.",
		},
		{
			Name: "JoinSyncGroup",
			Doc:  "// JoinSyncGroup is invoked on a SyncGroup Admin and checks if\n// the requestor can join the SyncGroup.",
		},
		{
			Name: "FetchBlob",
			Doc:  "// BlobSync methods.\n// FetchBlob returns the requested blob.",
		},
	},
}
