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

package mocks

import (
	context "context"

	mock "github.com/stretchr/testify/mock"
	docker "go.skia.org/infra/go/docker"
)

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

// GetConfig provides a mock function with given fields: ctx, registry, repository, configDigest
func (_m *Client) GetConfig(ctx context.Context, registry string, repository string, configDigest string) (*docker.ImageConfig, error) {
	ret := _m.Called(ctx, registry, repository, configDigest)

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

	var r0 *docker.ImageConfig
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (*docker.ImageConfig, error)); ok {
		return rf(ctx, registry, repository, configDigest)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string) *docker.ImageConfig); ok {
		r0 = rf(ctx, registry, repository, configDigest)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*docker.ImageConfig)
		}
	}

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

	return r0, r1
}

// GetManifest provides a mock function with given fields: ctx, registry, repository, reference
func (_m *Client) GetManifest(ctx context.Context, registry string, repository string, reference string) (*docker.Manifest, error) {
	ret := _m.Called(ctx, registry, repository, reference)

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

	var r0 *docker.Manifest
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (*docker.Manifest, error)); ok {
		return rf(ctx, registry, repository, reference)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string) *docker.Manifest); ok {
		r0 = rf(ctx, registry, repository, reference)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*docker.Manifest)
		}
	}

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

	return r0, r1
}

// ListInstances provides a mock function with given fields: ctx, registry, repository
func (_m *Client) ListInstances(ctx context.Context, registry string, repository string) (map[string]*docker.ImageInstance, error) {
	ret := _m.Called(ctx, registry, repository)

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

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

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

	return r0, r1
}

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

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

	var r0 []string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok {
		return rf(ctx, registry)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok {
		r0 = rf(ctx, registry)
	} 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, registry)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// ListTags provides a mock function with given fields: ctx, registry, repository
func (_m *Client) ListTags(ctx context.Context, registry string, repository string) ([]string, error) {
	ret := _m.Called(ctx, registry, repository)

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

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

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

	return r0, r1
}

// SetTag provides a mock function with given fields: ctx, registry, repository, reference, newTag
func (_m *Client) SetTag(ctx context.Context, registry string, repository string, reference string, newTag string) error {
	ret := _m.Called(ctx, registry, repository, reference, newTag)

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

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string) error); ok {
		r0 = rf(ctx, registry, repository, reference, newTag)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// NewClient creates a new instance of Client. 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 NewClient(t interface {
	mock.TestingT
	Cleanup(func())
}) *Client {
	mock := &Client{}
	mock.Mock.Test(t)

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

	return mock
}
