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

	testing "testing"
)

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

	var r0 *docker.ImageConfig
	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)
		}
	}

	var r1 error
	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)

	var r0 *docker.Manifest
	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)
		}
	}

	var r1 error
	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)

	var r0 map[string]*docker.ImageInstance
	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)
		}
	}

	var r1 error
	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)

	var r0 []string
	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)
		}
	}

	var r1 error
	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)

	var r0 []string
	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)
		}
	}

	var r1 error
	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)

	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 cleanup function to assert the mocks expectations.
func NewClient(t testing.TB) *Client {
	mock := &Client{}

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

	return mock
}
