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

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

import (
	reflect "reflect"

	gomock "github.com/golang/mock/gomock"
)

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

// 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 interface{}) *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 interface{}) *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 interface{}) *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 interface{}) *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 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSecondaryStagingStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).DeleteSecondaryStagingStore), p)
}

// GetImageStoreByID mocks base method.
func (m *MockImageStoreServiceIface) GetImageStoreByID(id string, opts ...OptionFunc) (*ImageStore, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{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 interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{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 := []interface{}{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 interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{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 := []interface{}{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 interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStoreID", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetImageStoreID), varargs...)
}

// GetSecondaryStagingStoreByID mocks base method.
func (m *MockImageStoreServiceIface) GetSecondaryStagingStoreByID(id string, opts ...OptionFunc) (*SecondaryStagingStore, int, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{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 interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{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 := []interface{}{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 interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{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 := []interface{}{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 interface{}, opts ...interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]interface{}{name}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecondaryStagingStoreID", reflect.TypeOf((*MockImageStoreServiceIface)(nil).GetSecondaryStagingStoreID), varargs...)
}

// 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 interface{}) *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 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSecondaryStagingStores", reflect.TypeOf((*MockImageStoreServiceIface)(nil).ListSecondaryStagingStores), 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 interface{}) *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 interface{}) *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 interface{}) *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 interface{}) *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 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteSecondaryStagingStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewDeleteSecondaryStagingStoreParams), 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))
}

// 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 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateCloudToUseObjectStoreParams", reflect.TypeOf((*MockImageStoreServiceIface)(nil).NewUpdateCloudToUseObjectStoreParams), provider)
}

// 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 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateCloudToUseObjectStore", reflect.TypeOf((*MockImageStoreServiceIface)(nil).UpdateCloudToUseObjectStore), p)
}
