// Code generated by mockery v0.0.0-dev. DO NOT EDIT.

package mocks

import (
	clientcipd "go.chromium.org/luci/cipd/client/cipd"
	cipd "go.skia.org/infra/go/cipd"

	common "go.chromium.org/luci/cipd/common"

	context "context"

	io "io"

	mock "github.com/stretchr/testify/mock"

	pkg "go.chromium.org/luci/cipd/client/cipd/pkg"

	regexp "regexp"

	time "time"
)

// CIPDClient is an autogenerated mock type for the CIPDClient type
type CIPDClient struct {
	mock.Mock
}

// Attach provides a mock function with given fields: ctx, pin, refs, tags, metadata
func (_m *CIPDClient) Attach(ctx context.Context, pin common.Pin, refs []string, tags []string, metadata map[string]string) error {
	ret := _m.Called(ctx, pin, refs, tags, metadata)

	if len(ret) == 0 {
		panic("no return value specified for Attach")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin, []string, []string, map[string]string) error); ok {
		r0 = rf(ctx, pin, refs, tags, metadata)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// AttachMetadataWhenReady provides a mock function with given fields: ctx, pin, md
func (_m *CIPDClient) AttachMetadataWhenReady(ctx context.Context, pin common.Pin, md []clientcipd.Metadata) error {
	ret := _m.Called(ctx, pin, md)

	if len(ret) == 0 {
		panic("no return value specified for AttachMetadataWhenReady")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin, []clientcipd.Metadata) error); ok {
		r0 = rf(ctx, pin, md)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// AttachTagsWhenReady provides a mock function with given fields: ctx, pin, tags
func (_m *CIPDClient) AttachTagsWhenReady(ctx context.Context, pin common.Pin, tags []string) error {
	ret := _m.Called(ctx, pin, tags)

	if len(ret) == 0 {
		panic("no return value specified for AttachTagsWhenReady")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin, []string) error); ok {
		r0 = rf(ctx, pin, tags)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// BeginBatch provides a mock function with given fields: ctx
func (_m *CIPDClient) BeginBatch(ctx context.Context) {
	_m.Called(ctx)
}

// Close provides a mock function with given fields: ctx
func (_m *CIPDClient) Close(ctx context.Context) {
	_m.Called(ctx)
}

// Create provides a mock function with given fields: ctx, name, dir, installMode, excludeMatchingFiles, refs, tags, metadata
func (_m *CIPDClient) Create(ctx context.Context, name string, dir string, installMode pkg.InstallMode, excludeMatchingFiles []*regexp.Regexp, refs []string, tags []string, metadata map[string]string) (common.Pin, error) {
	ret := _m.Called(ctx, name, dir, installMode, excludeMatchingFiles, refs, tags, metadata)

	if len(ret) == 0 {
		panic("no return value specified for Create")
	}

	var r0 common.Pin
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, pkg.InstallMode, []*regexp.Regexp, []string, []string, map[string]string) (common.Pin, error)); ok {
		return rf(ctx, name, dir, installMode, excludeMatchingFiles, refs, tags, metadata)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, string, pkg.InstallMode, []*regexp.Regexp, []string, []string, map[string]string) common.Pin); ok {
		r0 = rf(ctx, name, dir, installMode, excludeMatchingFiles, refs, tags, metadata)
	} else {
		r0 = ret.Get(0).(common.Pin)
	}

	if rf, ok := ret.Get(1).(func(context.Context, string, string, pkg.InstallMode, []*regexp.Regexp, []string, []string, map[string]string) error); ok {
		r1 = rf(ctx, name, dir, installMode, excludeMatchingFiles, refs, tags, metadata)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// Describe provides a mock function with given fields: ctx, _a1, instance, includeMetadata
func (_m *CIPDClient) Describe(ctx context.Context, _a1 string, instance string, includeMetadata bool) (*clientcipd.InstanceDescription, error) {
	ret := _m.Called(ctx, _a1, instance, includeMetadata)

	if len(ret) == 0 {
		panic("no return value specified for Describe")
	}

	var r0 *clientcipd.InstanceDescription
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, bool) (*clientcipd.InstanceDescription, error)); ok {
		return rf(ctx, _a1, instance, includeMetadata)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, string, bool) *clientcipd.InstanceDescription); ok {
		r0 = rf(ctx, _a1, instance, includeMetadata)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*clientcipd.InstanceDescription)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string, string, bool) error); ok {
		r1 = rf(ctx, _a1, instance, includeMetadata)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// DescribeClient provides a mock function with given fields: ctx, pin
func (_m *CIPDClient) DescribeClient(ctx context.Context, pin common.Pin) (*clientcipd.ClientDescription, error) {
	ret := _m.Called(ctx, pin)

	if len(ret) == 0 {
		panic("no return value specified for DescribeClient")
	}

	var r0 *clientcipd.ClientDescription
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin) (*clientcipd.ClientDescription, error)); ok {
		return rf(ctx, pin)
	}
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin) *clientcipd.ClientDescription); ok {
		r0 = rf(ctx, pin)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*clientcipd.ClientDescription)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, common.Pin) error); ok {
		r1 = rf(ctx, pin)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// DescribeInstance provides a mock function with given fields: ctx, pin, opts
func (_m *CIPDClient) DescribeInstance(ctx context.Context, pin common.Pin, opts *clientcipd.DescribeInstanceOpts) (*clientcipd.InstanceDescription, error) {
	ret := _m.Called(ctx, pin, opts)

	if len(ret) == 0 {
		panic("no return value specified for DescribeInstance")
	}

	var r0 *clientcipd.InstanceDescription
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin, *clientcipd.DescribeInstanceOpts) (*clientcipd.InstanceDescription, error)); ok {
		return rf(ctx, pin, opts)
	}
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin, *clientcipd.DescribeInstanceOpts) *clientcipd.InstanceDescription); ok {
		r0 = rf(ctx, pin, opts)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*clientcipd.InstanceDescription)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, common.Pin, *clientcipd.DescribeInstanceOpts) error); ok {
		r1 = rf(ctx, pin, opts)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// EndBatch provides a mock function with given fields: ctx
func (_m *CIPDClient) EndBatch(ctx context.Context) {
	_m.Called(ctx)
}

// Ensure provides a mock function with given fields: ctx, forceCopyInstallMode, packages
func (_m *CIPDClient) Ensure(ctx context.Context, forceCopyInstallMode bool, packages ...*cipd.Package) error {
	_va := make([]interface{}, len(packages))
	for _i := range packages {
		_va[_i] = packages[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, forceCopyInstallMode)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	if len(ret) == 0 {
		panic("no return value specified for Ensure")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, bool, ...*cipd.Package) error); ok {
		r0 = rf(ctx, forceCopyInstallMode, packages...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// EnsurePackages provides a mock function with given fields: ctx, pkgs, opts
func (_m *CIPDClient) EnsurePackages(ctx context.Context, pkgs common.PinSliceBySubdir, opts *clientcipd.EnsureOptions) (clientcipd.ActionMap, error) {
	ret := _m.Called(ctx, pkgs, opts)

	if len(ret) == 0 {
		panic("no return value specified for EnsurePackages")
	}

	var r0 clientcipd.ActionMap
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, common.PinSliceBySubdir, *clientcipd.EnsureOptions) (clientcipd.ActionMap, error)); ok {
		return rf(ctx, pkgs, opts)
	}
	if rf, ok := ret.Get(0).(func(context.Context, common.PinSliceBySubdir, *clientcipd.EnsureOptions) clientcipd.ActionMap); ok {
		r0 = rf(ctx, pkgs, opts)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(clientcipd.ActionMap)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, common.PinSliceBySubdir, *clientcipd.EnsureOptions) error); ok {
		r1 = rf(ctx, pkgs, opts)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// FetchACL provides a mock function with given fields: ctx, prefix
func (_m *CIPDClient) FetchACL(ctx context.Context, prefix string) ([]clientcipd.PackageACL, error) {
	ret := _m.Called(ctx, prefix)

	if len(ret) == 0 {
		panic("no return value specified for FetchACL")
	}

	var r0 []clientcipd.PackageACL
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]clientcipd.PackageACL, error)); ok {
		return rf(ctx, prefix)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []clientcipd.PackageACL); ok {
		r0 = rf(ctx, prefix)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]clientcipd.PackageACL)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
		r1 = rf(ctx, prefix)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// FetchInstance provides a mock function with given fields: ctx, pin
func (_m *CIPDClient) FetchInstance(ctx context.Context, pin common.Pin) (pkg.Source, error) {
	ret := _m.Called(ctx, pin)

	if len(ret) == 0 {
		panic("no return value specified for FetchInstance")
	}

	var r0 pkg.Source
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin) (pkg.Source, error)); ok {
		return rf(ctx, pin)
	}
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin) pkg.Source); ok {
		r0 = rf(ctx, pin)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(pkg.Source)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, common.Pin) error); ok {
		r1 = rf(ctx, pin)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// FetchInstanceTo provides a mock function with given fields: ctx, pin, output
func (_m *CIPDClient) FetchInstanceTo(ctx context.Context, pin common.Pin, output io.WriteSeeker) error {
	ret := _m.Called(ctx, pin, output)

	if len(ret) == 0 {
		panic("no return value specified for FetchInstanceTo")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin, io.WriteSeeker) error); ok {
		r0 = rf(ctx, pin, output)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// FetchPackageRefs provides a mock function with given fields: ctx, packageName
func (_m *CIPDClient) FetchPackageRefs(ctx context.Context, packageName string) ([]clientcipd.RefInfo, error) {
	ret := _m.Called(ctx, packageName)

	if len(ret) == 0 {
		panic("no return value specified for FetchPackageRefs")
	}

	var r0 []clientcipd.RefInfo
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]clientcipd.RefInfo, error)); ok {
		return rf(ctx, packageName)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []clientcipd.RefInfo); ok {
		r0 = rf(ctx, packageName)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]clientcipd.RefInfo)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
		r1 = rf(ctx, packageName)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// FetchRoles provides a mock function with given fields: ctx, prefix
func (_m *CIPDClient) FetchRoles(ctx context.Context, prefix string) ([]string, error) {
	ret := _m.Called(ctx, prefix)

	if len(ret) == 0 {
		panic("no return value specified for FetchRoles")
	}

	var r0 []string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok {
		return rf(ctx, prefix)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok {
		r0 = rf(ctx, prefix)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]string)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
		r1 = rf(ctx, prefix)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// FindDeployed provides a mock function with given fields: ctx
func (_m *CIPDClient) FindDeployed(ctx context.Context) (common.PinSliceBySubdir, error) {
	ret := _m.Called(ctx)

	if len(ret) == 0 {
		panic("no return value specified for FindDeployed")
	}

	var r0 common.PinSliceBySubdir
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context) (common.PinSliceBySubdir, error)); ok {
		return rf(ctx)
	}
	if rf, ok := ret.Get(0).(func(context.Context) common.PinSliceBySubdir); ok {
		r0 = rf(ctx)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(common.PinSliceBySubdir)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context) error); ok {
		r1 = rf(ctx)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// ListInstances provides a mock function with given fields: ctx, packageName
func (_m *CIPDClient) ListInstances(ctx context.Context, packageName string) (clientcipd.InstanceEnumerator, error) {
	ret := _m.Called(ctx, packageName)

	if len(ret) == 0 {
		panic("no return value specified for ListInstances")
	}

	var r0 clientcipd.InstanceEnumerator
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) (clientcipd.InstanceEnumerator, error)); ok {
		return rf(ctx, packageName)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) clientcipd.InstanceEnumerator); ok {
		r0 = rf(ctx, packageName)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(clientcipd.InstanceEnumerator)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
		r1 = rf(ctx, packageName)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// ListPackages provides a mock function with given fields: ctx, prefix, recursive, includeHidden
func (_m *CIPDClient) ListPackages(ctx context.Context, prefix string, recursive bool, includeHidden bool) ([]string, error) {
	ret := _m.Called(ctx, prefix, recursive, includeHidden)

	if len(ret) == 0 {
		panic("no return value specified for ListPackages")
	}

	var r0 []string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, bool, bool) ([]string, error)); ok {
		return rf(ctx, prefix, recursive, includeHidden)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, bool, bool) []string); ok {
		r0 = rf(ctx, prefix, recursive, includeHidden)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]string)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string, bool, bool) error); ok {
		r1 = rf(ctx, prefix, recursive, includeHidden)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// ModifyACL provides a mock function with given fields: ctx, prefix, changes
func (_m *CIPDClient) ModifyACL(ctx context.Context, prefix string, changes []clientcipd.PackageACLChange) error {
	ret := _m.Called(ctx, prefix, changes)

	if len(ret) == 0 {
		panic("no return value specified for ModifyACL")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, []clientcipd.PackageACLChange) error); ok {
		r0 = rf(ctx, prefix, changes)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// Options provides a mock function with given fields:
func (_m *CIPDClient) Options() clientcipd.ClientOptions {
	ret := _m.Called()

	if len(ret) == 0 {
		panic("no return value specified for Options")
	}

	var r0 clientcipd.ClientOptions
	if rf, ok := ret.Get(0).(func() clientcipd.ClientOptions); ok {
		r0 = rf()
	} else {
		r0 = ret.Get(0).(clientcipd.ClientOptions)
	}

	return r0
}

// RegisterInstance provides a mock function with given fields: ctx, pin, src, timeout
func (_m *CIPDClient) RegisterInstance(ctx context.Context, pin common.Pin, src pkg.Source, timeout time.Duration) error {
	ret := _m.Called(ctx, pin, src, timeout)

	if len(ret) == 0 {
		panic("no return value specified for RegisterInstance")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, common.Pin, pkg.Source, time.Duration) error); ok {
		r0 = rf(ctx, pin, src, timeout)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// ResolveVersion provides a mock function with given fields: ctx, packageName, version
func (_m *CIPDClient) ResolveVersion(ctx context.Context, packageName string, version string) (common.Pin, error) {
	ret := _m.Called(ctx, packageName, version)

	if len(ret) == 0 {
		panic("no return value specified for ResolveVersion")
	}

	var r0 common.Pin
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string) (common.Pin, error)); ok {
		return rf(ctx, packageName, version)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, string) common.Pin); ok {
		r0 = rf(ctx, packageName, version)
	} else {
		r0 = ret.Get(0).(common.Pin)
	}

	if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
		r1 = rf(ctx, packageName, version)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// SearchInstances provides a mock function with given fields: ctx, packageName, tags
func (_m *CIPDClient) SearchInstances(ctx context.Context, packageName string, tags []string) (common.PinSlice, error) {
	ret := _m.Called(ctx, packageName, tags)

	if len(ret) == 0 {
		panic("no return value specified for SearchInstances")
	}

	var r0 common.PinSlice
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, []string) (common.PinSlice, error)); ok {
		return rf(ctx, packageName, tags)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, []string) common.PinSlice); ok {
		r0 = rf(ctx, packageName, tags)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(common.PinSlice)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string, []string) error); ok {
		r1 = rf(ctx, packageName, tags)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// SetRefWhenReady provides a mock function with given fields: ctx, ref, pin
func (_m *CIPDClient) SetRefWhenReady(ctx context.Context, ref string, pin common.Pin) error {
	ret := _m.Called(ctx, ref, pin)

	if len(ret) == 0 {
		panic("no return value specified for SetRefWhenReady")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, common.Pin) error); ok {
		r0 = rf(ctx, ref, pin)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// NewCIPDClient creates a new instance of CIPDClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewCIPDClient(t interface {
	mock.TestingT
	Cleanup(func())
}) *CIPDClient {
	mock := &CIPDClient{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
