// 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: media.vdl

package media_sharing

import (
	"io"
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/rpc"
)

func __VDLEnsureNativeBuilt_media() {
}

// MediaSharingClientMethods is the client interface
// containing MediaSharing methods.
type MediaSharingClientMethods interface {
	// DisplayURL will cause the server to display whatever media is at
	// the given URL.  The server will rely on the ContentType response
	// header it gets when fetching the url to decide how to display
	// the media.
	DisplayUrl(_ *context.T, url string, _ ...rpc.CallOpt) error
	// DisplayBytes will cause the server to display whatever media is
	// sent in the stream.  In the case of audio or movie media, the
	// media should be played while the data is streaming.  The mediaType
	// can be used by the server to decide how to display the media.
	DisplayBytes(_ *context.T, mediaType string, _ ...rpc.CallOpt) (MediaSharingDisplayBytesClientCall, error)
}

// MediaSharingClientStub adds universal methods to MediaSharingClientMethods.
type MediaSharingClientStub interface {
	MediaSharingClientMethods
	rpc.UniversalServiceMethods
}

// MediaSharingClient returns a client stub for MediaSharing.
func MediaSharingClient(name string) MediaSharingClientStub {
	return implMediaSharingClientStub{name}
}

type implMediaSharingClientStub struct {
	name string
}

func (c implMediaSharingClientStub) DisplayUrl(ctx *context.T, i0 string, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "DisplayUrl", []interface{}{i0}, nil, opts...)
	return
}

func (c implMediaSharingClientStub) DisplayBytes(ctx *context.T, i0 string, opts ...rpc.CallOpt) (ocall MediaSharingDisplayBytesClientCall, err error) {
	var call rpc.ClientCall
	if call, err = v23.GetClient(ctx).StartCall(ctx, c.name, "DisplayBytes", []interface{}{i0}, opts...); err != nil {
		return
	}
	ocall = &implMediaSharingDisplayBytesClientCall{ClientCall: call}
	return
}

// MediaSharingDisplayBytesClientStream is the client stream for MediaSharing.DisplayBytes.
type MediaSharingDisplayBytesClientStream interface {
	// SendStream returns the send side of the MediaSharing.DisplayBytes client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item []byte) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	}
}

// MediaSharingDisplayBytesClientCall represents the call returned from MediaSharing.DisplayBytes.
type MediaSharingDisplayBytesClientCall interface {
	MediaSharingDisplayBytesClientStream
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() error
}

type implMediaSharingDisplayBytesClientCall struct {
	rpc.ClientCall
}

func (c *implMediaSharingDisplayBytesClientCall) SendStream() interface {
	Send(item []byte) error
	Close() error
} {
	return implMediaSharingDisplayBytesClientCallSend{c}
}

type implMediaSharingDisplayBytesClientCallSend struct {
	c *implMediaSharingDisplayBytesClientCall
}

func (c implMediaSharingDisplayBytesClientCallSend) Send(item []byte) error {
	return c.c.Send(item)
}
func (c implMediaSharingDisplayBytesClientCallSend) Close() error {
	return c.c.CloseSend()
}
func (c *implMediaSharingDisplayBytesClientCall) Finish() (err error) {
	err = c.ClientCall.Finish()
	return
}

// MediaSharingServerMethods is the interface a server writer
// implements for MediaSharing.
type MediaSharingServerMethods interface {
	// DisplayURL will cause the server to display whatever media is at
	// the given URL.  The server will rely on the ContentType response
	// header it gets when fetching the url to decide how to display
	// the media.
	DisplayUrl(_ *context.T, _ rpc.ServerCall, url string) error
	// DisplayBytes will cause the server to display whatever media is
	// sent in the stream.  In the case of audio or movie media, the
	// media should be played while the data is streaming.  The mediaType
	// can be used by the server to decide how to display the media.
	DisplayBytes(_ *context.T, _ MediaSharingDisplayBytesServerCall, mediaType string) error
}

// MediaSharingServerStubMethods is the server interface containing
// MediaSharing methods, as expected by rpc.Server.
// The only difference between this interface and MediaSharingServerMethods
// is the streaming methods.
type MediaSharingServerStubMethods interface {
	// DisplayURL will cause the server to display whatever media is at
	// the given URL.  The server will rely on the ContentType response
	// header it gets when fetching the url to decide how to display
	// the media.
	DisplayUrl(_ *context.T, _ rpc.ServerCall, url string) error
	// DisplayBytes will cause the server to display whatever media is
	// sent in the stream.  In the case of audio or movie media, the
	// media should be played while the data is streaming.  The mediaType
	// can be used by the server to decide how to display the media.
	DisplayBytes(_ *context.T, _ *MediaSharingDisplayBytesServerCallStub, mediaType string) error
}

// MediaSharingServerStub adds universal methods to MediaSharingServerStubMethods.
type MediaSharingServerStub interface {
	MediaSharingServerStubMethods
	// Describe the MediaSharing interfaces.
	Describe__() []rpc.InterfaceDesc
}

// MediaSharingServer returns a server stub for MediaSharing.
// It converts an implementation of MediaSharingServerMethods into
// an object that may be used by rpc.Server.
func MediaSharingServer(impl MediaSharingServerMethods) MediaSharingServerStub {
	stub := implMediaSharingServerStub{
		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 implMediaSharingServerStub struct {
	impl MediaSharingServerMethods
	gs   *rpc.GlobState
}

func (s implMediaSharingServerStub) DisplayUrl(ctx *context.T, call rpc.ServerCall, i0 string) error {
	return s.impl.DisplayUrl(ctx, call, i0)
}

func (s implMediaSharingServerStub) DisplayBytes(ctx *context.T, call *MediaSharingDisplayBytesServerCallStub, i0 string) error {
	return s.impl.DisplayBytes(ctx, call, i0)
}

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

func (s implMediaSharingServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{MediaSharingDesc}
}

// MediaSharingDesc describes the MediaSharing interface.
var MediaSharingDesc rpc.InterfaceDesc = descMediaSharing

// descMediaSharing hides the desc to keep godoc clean.
var descMediaSharing = rpc.InterfaceDesc{
	Name:    "MediaSharing",
	PkgPath: "v.io/x/media_sharing",
	Methods: []rpc.MethodDesc{
		{
			Name: "DisplayUrl",
			Doc:  "// DisplayURL will cause the server to display whatever media is at\n// the given URL.  The server will rely on the ContentType response\n// header it gets when fetching the url to decide how to display\n// the media.",
			InArgs: []rpc.ArgDesc{
				{"url", ``}, // string
			},
		},
		{
			Name: "DisplayBytes",
			Doc:  "// DisplayBytes will cause the server to display whatever media is\n// sent in the stream.  In the case of audio or movie media, the\n// media should be played while the data is streaming.  The mediaType\n// can be used by the server to decide how to display the media.",
			InArgs: []rpc.ArgDesc{
				{"mediaType", ``}, // string
			},
		},
	},
}

// MediaSharingDisplayBytesServerStream is the server stream for MediaSharing.DisplayBytes.
type MediaSharingDisplayBytesServerStream interface {
	// RecvStream returns the receiver side of the MediaSharing.DisplayBytes server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() []byte
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	}
}

// MediaSharingDisplayBytesServerCall represents the context passed to MediaSharing.DisplayBytes.
type MediaSharingDisplayBytesServerCall interface {
	rpc.ServerCall
	MediaSharingDisplayBytesServerStream
}

// MediaSharingDisplayBytesServerCallStub is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements MediaSharingDisplayBytesServerCall.
type MediaSharingDisplayBytesServerCallStub struct {
	rpc.StreamServerCall
	valRecv []byte
	errRecv error
}

// Init initializes MediaSharingDisplayBytesServerCallStub from rpc.StreamServerCall.
func (s *MediaSharingDisplayBytesServerCallStub) Init(call rpc.StreamServerCall) {
	s.StreamServerCall = call
}

// RecvStream returns the receiver side of the MediaSharing.DisplayBytes server stream.
func (s *MediaSharingDisplayBytesServerCallStub) RecvStream() interface {
	Advance() bool
	Value() []byte
	Err() error
} {
	return implMediaSharingDisplayBytesServerCallRecv{s}
}

type implMediaSharingDisplayBytesServerCallRecv struct {
	s *MediaSharingDisplayBytesServerCallStub
}

func (s implMediaSharingDisplayBytesServerCallRecv) Advance() bool {
	s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s implMediaSharingDisplayBytesServerCallRecv) Value() []byte {
	return s.s.valRecv
}
func (s implMediaSharingDisplayBytesServerCallRecv) Err() error {
	if s.s.errRecv == io.EOF {
		return nil
	}
	return s.s.errRecv
}
