//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//

// Code generated by MockGen. DO NOT EDIT.
// Source: ./cloudstack/ImageStoreService.go
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/ImageStoreService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/ImageStoreService.go
//

// Package cloudstack is a generated GoMock package.
package cloudstack

import (
	reflect "reflect"

	gomock "go.uber.org/mock/gomock"
)

// MockImageStoreServiceIface is a mock of ImageStoreServiceIface interface.
type MockImageStoreServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockImageStoreServiceIfaceMockRecorder
	isgomock struct{}
}

// MockImageStoreServiceIfaceMockRecorder is the mock recorder for MockImageStoreServiceIface.
type MockImageStoreServiceIfaceMockRecorder struct {
	mock *MockImageStoreServiceIface
}

// NewMockImageStoreServiceIface creates a new mock instance.
func NewMockImageStoreServiceIface(ctrl *gomock.Controller) *MockImageStoreServiceIface {
	mock := &MockImageStoreServiceIface{ctrl: ctrl}
	mock.recorder = &MockImageStoreServiceIfaceMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockImageStoreServiceIface) EXPECT() *MockImageStoreServiceIfaceMockRecorder {
	return m.recorder
}

// AddImageStore mocks base method.
func (m *MockImageStoreServiceIface) AddImageStore(p *AddImageStoreParams) (*AddImageStoreResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddImageStore", p)
	ret0, _ := ret[0].(*AddImageStoreResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// AddImageStore indicates an expected call of AddImageStore.
func (mr *MockImageStoreServiceIfaceMockRecorder) AddImageStore(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddImageStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).AddImageStore), p)
}

// AddImageStoreS3 mocks base method.
func (m *MockImageStoreServiceIface) AddImageStoreS3(p *AddImageStoreS3Params) (*AddImageStoreS3Response, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddImageStoreS3", p)
	ret0, _ := ret[0].(*AddImageStoreS3Response)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// AddImageStoreS3 indicates an expected call of AddImageStoreS3.
func (mr *MockImageStoreServiceIfaceMockRecorder) AddImageStoreS3(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddImageStoreS3", reflect.TypeOf((*MockImageStoreServiceIface)(nil).AddImageStoreS3), p)
}

// CreateSecondaryStagingStore mocks base method.
func (m *MockImageStoreServiceIface) CreateSecondaryStagingStore(p *CreateSecondaryStagingStoreParams) (*CreateSecondaryStagingStoreResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateSecondaryStagingStore", p)
	ret0, _ := ret[0].(*CreateSecondaryStagingStoreResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateSecondaryStagingStore indicates an expected call of CreateSecondaryStagingStore.
func (mr *MockImageStoreServiceIfaceMockRecorder) CreateSecondaryStagingStore(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSecondaryStagingStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).CreateSecondaryStagingStore), p)
}

// DeleteImageStore mocks base method.
func (m *MockImageStoreServiceIface) DeleteImageStore(p *DeleteImageStoreParams) (*DeleteImageStoreResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteImageStore", p)
	ret0, _ := ret[0].(*DeleteImageStoreResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteImageStore indicates an expected call of DeleteImageStore.
func (mr *MockImageStoreServiceIfaceMockRecorder) DeleteImageStore(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteImageStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).DeleteImageStore), p)
}

// DeleteSecondaryStagingStore mocks base method.
func (m *MockImageStoreServiceIface) DeleteSecondaryStagingStore(p *DeleteSecondaryStagingStoreParams) (*DeleteSecondaryStagingStoreResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteSecondaryStagingStore", p)
	ret0, _ := ret[0].(*DeleteSecondaryStagingStoreResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteSecondaryStagingStore indicates an expected call of DeleteSecondaryStagingStore.
func (mr *MockImageStoreServiceIfaceMockRecorder) DeleteSecondaryStagingStore(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSecondaryStagingStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).DeleteSecondaryStagingStore), p)
}

// DownloadImageStoreObject mocks base method.
func (m *MockImageStoreServiceIface) DownloadImageStoreObject(p *DownloadImageStoreObjectParams) (*DownloadImageStoreObjectResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DownloadImageStoreObject", p)
	ret0, _ := ret[0].(*DownloadImageStoreObjectResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DownloadImageStoreObject indicates an expected call of DownloadImageStoreObject.
func (mr *MockImageStoreServiceIfaceMockRecorder) DownloadImageStoreObject(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImageStoreObject", reflect.TypeOf((*MockImageStoreServiceIface)(nil).DownloadImageStoreObject), p)
}

// GetImageStoreByID mocks base method.
func (m *MockImageStoreServiceIface) GetImageStoreByID(id string, opts ...OptionFunc) (*ImageStore, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImageStoreByID", varargs...)
	ret0, _ := ret[0].(*ImageStore)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetImageStoreByID indicates an expected call of GetImageStoreByID.
func (mr *MockImageStoreServiceIfaceMockRecorder) GetImageStoreByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStoreByID", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetImageStoreByID), varargs...)
}

// GetImageStoreByName mocks base method.
func (m *MockImageStoreServiceIface) GetImageStoreByName(name string, opts ...OptionFunc) (*ImageStore, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImageStoreByName", varargs...)
	ret0, _ := ret[0].(*ImageStore)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetImageStoreByName indicates an expected call of GetImageStoreByName.
func (mr *MockImageStoreServiceIfaceMockRecorder) GetImageStoreByName(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStoreByName", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetImageStoreByName), varargs...)
}

// GetImageStoreID mocks base method.
func (m *MockImageStoreServiceIface) GetImageStoreID(name string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImageStoreID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetImageStoreID indicates an expected call of GetImageStoreID.
func (mr *MockImageStoreServiceIfaceMockRecorder) GetImageStoreID(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStoreID", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetImageStoreID), varargs...)
}

// GetImageStoreObjectByID mocks base method.
func (m *MockImageStoreServiceIface) GetImageStoreObjectByID(id string, opts ...OptionFunc) (*ImageStoreObject, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImageStoreObjectByID", varargs...)
	ret0, _ := ret[0].(*ImageStoreObject)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetImageStoreObjectByID indicates an expected call of GetImageStoreObjectByID.
func (mr *MockImageStoreServiceIfaceMockRecorder) GetImageStoreObjectByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStoreObjectByID", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetImageStoreObjectByID), varargs...)
}

// GetSecondaryStagingStoreByID mocks base method.
func (m *MockImageStoreServiceIface) GetSecondaryStagingStoreByID(id string, opts ...OptionFunc) (*SecondaryStagingStore, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{id}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetSecondaryStagingStoreByID", varargs...)
	ret0, _ := ret[0].(*SecondaryStagingStore)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetSecondaryStagingStoreByID indicates an expected call of GetSecondaryStagingStoreByID.
func (mr *MockImageStoreServiceIfaceMockRecorder) GetSecondaryStagingStoreByID(id any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{id}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecondaryStagingStoreByID", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetSecondaryStagingStoreByID), varargs...)
}

// GetSecondaryStagingStoreByName mocks base method.
func (m *MockImageStoreServiceIface) GetSecondaryStagingStoreByName(name string, opts ...OptionFunc) (*SecondaryStagingStore, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetSecondaryStagingStoreByName", varargs...)
	ret0, _ := ret[0].(*SecondaryStagingStore)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetSecondaryStagingStoreByName indicates an expected call of GetSecondaryStagingStoreByName.
func (mr *MockImageStoreServiceIfaceMockRecorder) GetSecondaryStagingStoreByName(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecondaryStagingStoreByName", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetSecondaryStagingStoreByName), varargs...)
}

// GetSecondaryStagingStoreID mocks base method.
func (m *MockImageStoreServiceIface) GetSecondaryStagingStoreID(name string, opts ...OptionFunc) (string, int, error) {
	m.ctrl.T.Helper()
	varargs := []any{name}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetSecondaryStagingStoreID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetSecondaryStagingStoreID indicates an expected call of GetSecondaryStagingStoreID.
func (mr *MockImageStoreServiceIfaceMockRecorder) GetSecondaryStagingStoreID(name any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecondaryStagingStoreID", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetSecondaryStagingStoreID), varargs...)
}

// ListImageStoreObjects mocks base method.
func (m *MockImageStoreServiceIface) ListImageStoreObjects(p *ListImageStoreObjectsParams) (*ListImageStoreObjectsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListImageStoreObjects", p)
	ret0, _ := ret[0].(*ListImageStoreObjectsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListImageStoreObjects indicates an expected call of ListImageStoreObjects.
func (mr *MockImageStoreServiceIfaceMockRecorder) ListImageStoreObjects(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImageStoreObjects", reflect.TypeOf((*MockImageStoreServiceIface)(nil).ListImageStoreObjects), p)
}

// ListImageStores mocks base method.
func (m *MockImageStoreServiceIface) ListImageStores(p *ListImageStoresParams) (*ListImageStoresResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListImageStores", p)
	ret0, _ := ret[0].(*ListImageStoresResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListImageStores indicates an expected call of ListImageStores.
func (mr *MockImageStoreServiceIfaceMockRecorder) ListImageStores(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImageStores", reflect.TypeOf((*MockImageStoreServiceIface)(nil).ListImageStores), p)
}

// ListSecondaryStagingStores mocks base method.
func (m *MockImageStoreServiceIface) ListSecondaryStagingStores(p *ListSecondaryStagingStoresParams) (*ListSecondaryStagingStoresResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListSecondaryStagingStores", p)
	ret0, _ := ret[0].(*ListSecondaryStagingStoresResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListSecondaryStagingStores indicates an expected call of ListSecondaryStagingStores.
func (mr *MockImageStoreServiceIfaceMockRecorder) ListSecondaryStagingStores(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSecondaryStagingStores", reflect.TypeOf((*MockImageStoreServiceIface)(nil).ListSecondaryStagingStores), p)
}

// MigrateResourceToAnotherSecondaryStorage mocks base method.
func (m *MockImageStoreServiceIface) MigrateResourceToAnotherSecondaryStorage(p *MigrateResourceToAnotherSecondaryStorageParams) (*MigrateResourceToAnotherSecondaryStorageResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "MigrateResourceToAnotherSecondaryStorage", p)
	ret0, _ := ret[0].(*MigrateResourceToAnotherSecondaryStorageResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// MigrateResourceToAnotherSecondaryStorage indicates an expected call of MigrateResourceToAnotherSecondaryStorage.
func (mr *MockImageStoreServiceIfaceMockRecorder) MigrateResourceToAnotherSecondaryStorage(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MigrateResourceToAnotherSecondaryStorage", reflect.TypeOf((*MockImageStoreServiceIface)(nil).MigrateResourceToAnotherSecondaryStorage), p)
}

// NewAddImageStoreParams mocks base method.
func (m *MockImageStoreServiceIface) NewAddImageStoreParams(provider string) *AddImageStoreParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddImageStoreParams", provider)
	ret0, _ := ret[0].(*AddImageStoreParams)
	return ret0
}

// NewAddImageStoreParams indicates an expected call of NewAddImageStoreParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewAddImageStoreParams(provider any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddImageStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewAddImageStoreParams), provider)
}

// NewAddImageStoreS3Params mocks base method.
func (m *MockImageStoreServiceIface) NewAddImageStoreS3Params(accesskey, bucket, endpoint, secretkey string) *AddImageStoreS3Params {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddImageStoreS3Params", accesskey, bucket, endpoint, secretkey)
	ret0, _ := ret[0].(*AddImageStoreS3Params)
	return ret0
}

// NewAddImageStoreS3Params indicates an expected call of NewAddImageStoreS3Params.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewAddImageStoreS3Params(accesskey, bucket, endpoint, secretkey any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddImageStoreS3Params", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewAddImageStoreS3Params), accesskey, bucket, endpoint, secretkey)
}

// NewCreateSecondaryStagingStoreParams mocks base method.
func (m *MockImageStoreServiceIface) NewCreateSecondaryStagingStoreParams(url string) *CreateSecondaryStagingStoreParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateSecondaryStagingStoreParams", url)
	ret0, _ := ret[0].(*CreateSecondaryStagingStoreParams)
	return ret0
}

// NewCreateSecondaryStagingStoreParams indicates an expected call of NewCreateSecondaryStagingStoreParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewCreateSecondaryStagingStoreParams(url any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateSecondaryStagingStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewCreateSecondaryStagingStoreParams), url)
}

// NewDeleteImageStoreParams mocks base method.
func (m *MockImageStoreServiceIface) NewDeleteImageStoreParams(id string) *DeleteImageStoreParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteImageStoreParams", id)
	ret0, _ := ret[0].(*DeleteImageStoreParams)
	return ret0
}

// NewDeleteImageStoreParams indicates an expected call of NewDeleteImageStoreParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewDeleteImageStoreParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteImageStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewDeleteImageStoreParams), id)
}

// NewDeleteSecondaryStagingStoreParams mocks base method.
func (m *MockImageStoreServiceIface) NewDeleteSecondaryStagingStoreParams(id string) *DeleteSecondaryStagingStoreParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteSecondaryStagingStoreParams", id)
	ret0, _ := ret[0].(*DeleteSecondaryStagingStoreParams)
	return ret0
}

// NewDeleteSecondaryStagingStoreParams indicates an expected call of NewDeleteSecondaryStagingStoreParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewDeleteSecondaryStagingStoreParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteSecondaryStagingStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewDeleteSecondaryStagingStoreParams), id)
}

// NewDownloadImageStoreObjectParams mocks base method.
func (m *MockImageStoreServiceIface) NewDownloadImageStoreObjectParams(id string) *DownloadImageStoreObjectParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDownloadImageStoreObjectParams", id)
	ret0, _ := ret[0].(*DownloadImageStoreObjectParams)
	return ret0
}

// NewDownloadImageStoreObjectParams indicates an expected call of NewDownloadImageStoreObjectParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewDownloadImageStoreObjectParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDownloadImageStoreObjectParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewDownloadImageStoreObjectParams), id)
}

// NewListImageStoreObjectsParams mocks base method.
func (m *MockImageStoreServiceIface) NewListImageStoreObjectsParams(id string) *ListImageStoreObjectsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListImageStoreObjectsParams", id)
	ret0, _ := ret[0].(*ListImageStoreObjectsParams)
	return ret0
}

// NewListImageStoreObjectsParams indicates an expected call of NewListImageStoreObjectsParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewListImageStoreObjectsParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListImageStoreObjectsParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewListImageStoreObjectsParams), id)
}

// NewListImageStoresParams mocks base method.
func (m *MockImageStoreServiceIface) NewListImageStoresParams() *ListImageStoresParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListImageStoresParams")
	ret0, _ := ret[0].(*ListImageStoresParams)
	return ret0
}

// NewListImageStoresParams indicates an expected call of NewListImageStoresParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewListImageStoresParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListImageStoresParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewListImageStoresParams))
}

// NewListSecondaryStagingStoresParams mocks base method.
func (m *MockImageStoreServiceIface) NewListSecondaryStagingStoresParams() *ListSecondaryStagingStoresParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListSecondaryStagingStoresParams")
	ret0, _ := ret[0].(*ListSecondaryStagingStoresParams)
	return ret0
}

// NewListSecondaryStagingStoresParams indicates an expected call of NewListSecondaryStagingStoresParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewListSecondaryStagingStoresParams() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListSecondaryStagingStoresParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewListSecondaryStagingStoresParams))
}

// NewMigrateResourceToAnotherSecondaryStorageParams mocks base method.
func (m *MockImageStoreServiceIface) NewMigrateResourceToAnotherSecondaryStorageParams(destpool, srcpool string) *MigrateResourceToAnotherSecondaryStorageParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewMigrateResourceToAnotherSecondaryStorageParams", destpool, srcpool)
	ret0, _ := ret[0].(*MigrateResourceToAnotherSecondaryStorageParams)
	return ret0
}

// NewMigrateResourceToAnotherSecondaryStorageParams indicates an expected call of NewMigrateResourceToAnotherSecondaryStorageParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewMigrateResourceToAnotherSecondaryStorageParams(destpool, srcpool any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewMigrateResourceToAnotherSecondaryStorageParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewMigrateResourceToAnotherSecondaryStorageParams), destpool, srcpool)
}

// NewUpdateCloudToUseObjectStoreParams mocks base method.
func (m *MockImageStoreServiceIface) NewUpdateCloudToUseObjectStoreParams(provider string) *UpdateCloudToUseObjectStoreParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateCloudToUseObjectStoreParams", provider)
	ret0, _ := ret[0].(*UpdateCloudToUseObjectStoreParams)
	return ret0
}

// NewUpdateCloudToUseObjectStoreParams indicates an expected call of NewUpdateCloudToUseObjectStoreParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewUpdateCloudToUseObjectStoreParams(provider any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateCloudToUseObjectStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewUpdateCloudToUseObjectStoreParams), provider)
}

// NewUpdateImageStoreParams mocks base method.
func (m *MockImageStoreServiceIface) NewUpdateImageStoreParams(id string) *UpdateImageStoreParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateImageStoreParams", id)
	ret0, _ := ret[0].(*UpdateImageStoreParams)
	return ret0
}

// NewUpdateImageStoreParams indicates an expected call of NewUpdateImageStoreParams.
func (mr *MockImageStoreServiceIfaceMockRecorder) NewUpdateImageStoreParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateImageStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewUpdateImageStoreParams), id)
}

// UpdateCloudToUseObjectStore mocks base method.
func (m *MockImageStoreServiceIface) UpdateCloudToUseObjectStore(p *UpdateCloudToUseObjectStoreParams) (*UpdateCloudToUseObjectStoreResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateCloudToUseObjectStore", p)
	ret0, _ := ret[0].(*UpdateCloudToUseObjectStoreResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateCloudToUseObjectStore indicates an expected call of UpdateCloudToUseObjectStore.
func (mr *MockImageStoreServiceIfaceMockRecorder) UpdateCloudToUseObjectStore(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateCloudToUseObjectStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).UpdateCloudToUseObjectStore), p)
}

// UpdateImageStore mocks base method.
func (m *MockImageStoreServiceIface) UpdateImageStore(p *UpdateImageStoreParams) (*UpdateImageStoreResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateImageStore", p)
	ret0, _ := ret[0].(*UpdateImageStoreResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateImageStore indicates an expected call of UpdateImageStore.
func (mr *MockImageStoreServiceIfaceMockRecorder) UpdateImageStore(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateImageStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).UpdateImageStore), p)
}
