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

// Package repository augments the v.io/v23/services/repository interfaces with
// implementation-specific configuration methods.
package repository

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

	// VDL user imports
	"v.io/v23/security/access"
	"v.io/v23/services/application"
	"v.io/v23/services/permissions"
	"v.io/v23/services/repository"
	"v.io/v23/services/tidyable"
	"v.io/x/ref/services/profile"
)

// ApplicationClientMethods is the client interface
// containing Application methods.
//
// Application describes an application repository internally. Besides the
// public Application interface, it allows adding and removing application
// envelopes, as well as querying for a list of supported profiles.
type ApplicationClientMethods interface {
	// Application provides access to application envelopes. An
	// application envelope is identified by an application name and an
	// application version, which are specified through the object name,
	// and a profile name, which is specified using a method argument.
	//
	// Example:
	// /apps/search/v1.Match([]string{"base", "media"})
	//   returns an application envelope that can be used for downloading
	//   and executing the "search" application, version "v1", runnable
	//   on either the "base" or "media" profile.
	repository.ApplicationClientMethods
	// Put adds the given application envelope for the given profile and
	// application version (required, and specified through the object name
	// suffix).
	//
	// An error is returned if an envelope already exists, unless the
	// overwrite option is set.
	Put(ctx *context.T, Profile string, Envelope application.Envelope, Overwrite bool, opts ...rpc.CallOpt) error
	// DEPRECATED. Please use Put for new code.
	PutX(ctx *context.T, Profile string, Envelope application.Envelope, Overwrite bool, opts ...rpc.CallOpt) error
	// Remove removes the application envelope for the given profile
	// name and application version (specified through the object name
	// suffix).
	//
	// If no version is specified as part of the suffix, the method removes
	// all versions for the given profile.
	//
	// If the profile is the string "*", all profiles are removed for the
	// given version (or for all versions if the version is not specified).
	Remove(ctx *context.T, Profile string, opts ...rpc.CallOpt) error
	// Profiles returns the supported profiles for the application version
	// specified through the object name suffix.  If the version is not
	// specified, Profiles returns the union of profiles across all
	// versions.
	Profiles(*context.T, ...rpc.CallOpt) ([]string, error)
}

// ApplicationClientStub adds universal methods to ApplicationClientMethods.
type ApplicationClientStub interface {
	ApplicationClientMethods
	rpc.UniversalServiceMethods
}

// ApplicationClient returns a client stub for Application.
func ApplicationClient(name string) ApplicationClientStub {
	return implApplicationClientStub{name, repository.ApplicationClient(name)}
}

type implApplicationClientStub struct {
	name string

	repository.ApplicationClientStub
}

func (c implApplicationClientStub) Put(ctx *context.T, i0 string, i1 application.Envelope, i2 bool, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Put", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

func (c implApplicationClientStub) PutX(ctx *context.T, i0 string, i1 application.Envelope, i2 bool, opts ...rpc.CallOpt) (err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "PutX", []interface{}{i0, i1, i2}, nil, opts...)
	return
}

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

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

// ApplicationServerMethods is the interface a server writer
// implements for Application.
//
// Application describes an application repository internally. Besides the
// public Application interface, it allows adding and removing application
// envelopes, as well as querying for a list of supported profiles.
type ApplicationServerMethods interface {
	// Application provides access to application envelopes. An
	// application envelope is identified by an application name and an
	// application version, which are specified through the object name,
	// and a profile name, which is specified using a method argument.
	//
	// Example:
	// /apps/search/v1.Match([]string{"base", "media"})
	//   returns an application envelope that can be used for downloading
	//   and executing the "search" application, version "v1", runnable
	//   on either the "base" or "media" profile.
	repository.ApplicationServerMethods
	// Put adds the given application envelope for the given profile and
	// application version (required, and specified through the object name
	// suffix).
	//
	// An error is returned if an envelope already exists, unless the
	// overwrite option is set.
	Put(ctx *context.T, call rpc.ServerCall, Profile string, Envelope application.Envelope, Overwrite bool) error
	// DEPRECATED. Please use Put for new code.
	PutX(ctx *context.T, call rpc.ServerCall, Profile string, Envelope application.Envelope, Overwrite bool) error
	// Remove removes the application envelope for the given profile
	// name and application version (specified through the object name
	// suffix).
	//
	// If no version is specified as part of the suffix, the method removes
	// all versions for the given profile.
	//
	// If the profile is the string "*", all profiles are removed for the
	// given version (or for all versions if the version is not specified).
	Remove(ctx *context.T, call rpc.ServerCall, Profile string) error
	// Profiles returns the supported profiles for the application version
	// specified through the object name suffix.  If the version is not
	// specified, Profiles returns the union of profiles across all
	// versions.
	Profiles(*context.T, rpc.ServerCall) ([]string, error)
}

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

// ApplicationServerStub adds universal methods to ApplicationServerStubMethods.
type ApplicationServerStub interface {
	ApplicationServerStubMethods
	// Describe the Application interfaces.
	Describe__() []rpc.InterfaceDesc
}

// ApplicationServer returns a server stub for Application.
// It converts an implementation of ApplicationServerMethods into
// an object that may be used by rpc.Server.
func ApplicationServer(impl ApplicationServerMethods) ApplicationServerStub {
	stub := implApplicationServerStub{
		impl: impl,
		ApplicationServerStub: repository.ApplicationServer(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 implApplicationServerStub struct {
	impl ApplicationServerMethods
	repository.ApplicationServerStub
	gs *rpc.GlobState
}

func (s implApplicationServerStub) Put(ctx *context.T, call rpc.ServerCall, i0 string, i1 application.Envelope, i2 bool) error {
	return s.impl.Put(ctx, call, i0, i1, i2)
}

func (s implApplicationServerStub) PutX(ctx *context.T, call rpc.ServerCall, i0 string, i1 application.Envelope, i2 bool) error {
	return s.impl.PutX(ctx, call, i0, i1, i2)
}

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

func (s implApplicationServerStub) Profiles(ctx *context.T, call rpc.ServerCall) ([]string, error) {
	return s.impl.Profiles(ctx, call)
}

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

func (s implApplicationServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ApplicationDesc, repository.ApplicationDesc, permissions.ObjectDesc, tidyable.TidyableDesc}
}

// ApplicationDesc describes the Application interface.
var ApplicationDesc rpc.InterfaceDesc = descApplication

// descApplication hides the desc to keep godoc clean.
var descApplication = rpc.InterfaceDesc{
	Name:    "Application",
	PkgPath: "v.io/x/ref/services/repository",
	Doc:     "// Application describes an application repository internally. Besides the\n// public Application interface, it allows adding and removing application\n// envelopes, as well as querying for a list of supported profiles.",
	Embeds: []rpc.EmbedDesc{
		{"Application", "v.io/v23/services/repository", "// Application provides access to application envelopes. An\n// application envelope is identified by an application name and an\n// application version, which are specified through the object name,\n// and a profile name, which is specified using a method argument.\n//\n// Example:\n// /apps/search/v1.Match([]string{\"base\", \"media\"})\n//   returns an application envelope that can be used for downloading\n//   and executing the \"search\" application, version \"v1\", runnable\n//   on either the \"base\" or \"media\" profile."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Put",
			Doc:  "// Put adds the given application envelope for the given profile and\n// application version (required, and specified through the object name\n// suffix).\n//\n// An error is returned if an envelope already exists, unless the\n// overwrite option is set.",
			InArgs: []rpc.ArgDesc{
				{"Profile", ``},   // string
				{"Envelope", ``},  // application.Envelope
				{"Overwrite", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "PutX",
			Doc:  "// DEPRECATED. Please use Put for new code.",
			InArgs: []rpc.ArgDesc{
				{"Profile", ``},   // string
				{"Envelope", ``},  // application.Envelope
				{"Overwrite", ``}, // bool
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Remove",
			Doc:  "// Remove removes the application envelope for the given profile\n// name and application version (specified through the object name\n// suffix).\n//\n// If no version is specified as part of the suffix, the method removes\n// all versions for the given profile.\n//\n// If the profile is the string \"*\", all profiles are removed for the\n// given version (or for all versions if the version is not specified).",
			InArgs: []rpc.ArgDesc{
				{"Profile", ``}, // string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Profiles",
			Doc:  "// Profiles returns the supported profiles for the application version\n// specified through the object name suffix.  If the version is not\n// specified, Profiles returns the union of profiles across all\n// versions.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // []string
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
	},
}

// ProfileClientMethods is the client interface
// containing Profile methods.
//
// Profile describes a profile internally. Besides the public Profile
// interface, it allows to add and remove profile specifications.
type ProfileClientMethods interface {
	// Profile abstracts a device's ability to run binaries, and hides
	// specifics such as the operating system, hardware architecture, and
	// the set of installed libraries. Profiles describe binaries and
	// devices, and are used to match them.
	repository.ProfileClientMethods
	// Specification returns the profile specification for the profile
	// identified through the object name suffix.
	Specification(*context.T, ...rpc.CallOpt) (profile.Specification, error)
	// Put sets the profile specification for the profile identified
	// through the object name suffix.
	Put(ctx *context.T, Specification profile.Specification, opts ...rpc.CallOpt) error
	// Remove removes the profile specification for the profile
	// identified through the object name suffix.
	Remove(*context.T, ...rpc.CallOpt) error
}

// ProfileClientStub adds universal methods to ProfileClientMethods.
type ProfileClientStub interface {
	ProfileClientMethods
	rpc.UniversalServiceMethods
}

// ProfileClient returns a client stub for Profile.
func ProfileClient(name string) ProfileClientStub {
	return implProfileClientStub{name, repository.ProfileClient(name)}
}

type implProfileClientStub struct {
	name string

	repository.ProfileClientStub
}

func (c implProfileClientStub) Specification(ctx *context.T, opts ...rpc.CallOpt) (o0 profile.Specification, err error) {
	err = v23.GetClient(ctx).Call(ctx, c.name, "Specification", nil, []interface{}{&o0}, opts...)
	return
}

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

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

// ProfileServerMethods is the interface a server writer
// implements for Profile.
//
// Profile describes a profile internally. Besides the public Profile
// interface, it allows to add and remove profile specifications.
type ProfileServerMethods interface {
	// Profile abstracts a device's ability to run binaries, and hides
	// specifics such as the operating system, hardware architecture, and
	// the set of installed libraries. Profiles describe binaries and
	// devices, and are used to match them.
	repository.ProfileServerMethods
	// Specification returns the profile specification for the profile
	// identified through the object name suffix.
	Specification(*context.T, rpc.ServerCall) (profile.Specification, error)
	// Put sets the profile specification for the profile identified
	// through the object name suffix.
	Put(ctx *context.T, call rpc.ServerCall, Specification profile.Specification) error
	// Remove removes the profile specification for the profile
	// identified through the object name suffix.
	Remove(*context.T, rpc.ServerCall) error
}

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

// ProfileServerStub adds universal methods to ProfileServerStubMethods.
type ProfileServerStub interface {
	ProfileServerStubMethods
	// Describe the Profile interfaces.
	Describe__() []rpc.InterfaceDesc
}

// ProfileServer returns a server stub for Profile.
// It converts an implementation of ProfileServerMethods into
// an object that may be used by rpc.Server.
func ProfileServer(impl ProfileServerMethods) ProfileServerStub {
	stub := implProfileServerStub{
		impl:              impl,
		ProfileServerStub: repository.ProfileServer(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 implProfileServerStub struct {
	impl ProfileServerMethods
	repository.ProfileServerStub
	gs *rpc.GlobState
}

func (s implProfileServerStub) Specification(ctx *context.T, call rpc.ServerCall) (profile.Specification, error) {
	return s.impl.Specification(ctx, call)
}

func (s implProfileServerStub) Put(ctx *context.T, call rpc.ServerCall, i0 profile.Specification) error {
	return s.impl.Put(ctx, call, i0)
}

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

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

func (s implProfileServerStub) Describe__() []rpc.InterfaceDesc {
	return []rpc.InterfaceDesc{ProfileDesc, repository.ProfileDesc}
}

// ProfileDesc describes the Profile interface.
var ProfileDesc rpc.InterfaceDesc = descProfile

// descProfile hides the desc to keep godoc clean.
var descProfile = rpc.InterfaceDesc{
	Name:    "Profile",
	PkgPath: "v.io/x/ref/services/repository",
	Doc:     "// Profile describes a profile internally. Besides the public Profile\n// interface, it allows to add and remove profile specifications.",
	Embeds: []rpc.EmbedDesc{
		{"Profile", "v.io/v23/services/repository", "// Profile abstracts a device's ability to run binaries, and hides\n// specifics such as the operating system, hardware architecture, and\n// the set of installed libraries. Profiles describe binaries and\n// devices, and are used to match them."},
	},
	Methods: []rpc.MethodDesc{
		{
			Name: "Specification",
			Doc:  "// Specification returns the profile specification for the profile\n// identified through the object name suffix.",
			OutArgs: []rpc.ArgDesc{
				{"", ``}, // profile.Specification
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Read"))},
		},
		{
			Name: "Put",
			Doc:  "// Put sets the profile specification for the profile identified\n// through the object name suffix.",
			InArgs: []rpc.ArgDesc{
				{"Specification", ``}, // profile.Specification
			},
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
		{
			Name: "Remove",
			Doc:  "// Remove removes the profile specification for the profile\n// identified through the object name suffix.",
			Tags: []*vdl.Value{vdl.ValueOf(access.Tag("Write"))},
		},
	},
}
