//
// 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/ResourceIconService.go
//
// Generated by this command:
//
//	mockgen -destination=./cloudstack/ResourceIconService_mock.go -package=cloudstack -copyright_file=header.txt -source=./cloudstack/ResourceIconService.go
//

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

import (
	reflect "reflect"

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

// MockResourceIconServiceIface is a mock of ResourceIconServiceIface interface.
type MockResourceIconServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockResourceIconServiceIfaceMockRecorder
	isgomock struct{}
}

// MockResourceIconServiceIfaceMockRecorder is the mock recorder for MockResourceIconServiceIface.
type MockResourceIconServiceIfaceMockRecorder struct {
	mock *MockResourceIconServiceIface
}

// NewMockResourceIconServiceIface creates a new mock instance.
func NewMockResourceIconServiceIface(ctrl *gomock.Controller) *MockResourceIconServiceIface {
	mock := &MockResourceIconServiceIface{ctrl: ctrl}
	mock.recorder = &MockResourceIconServiceIfaceMockRecorder{mock}
	return mock
}

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

// DeleteResourceIcon mocks base method.
func (m *MockResourceIconServiceIface) DeleteResourceIcon(p *DeleteResourceIconParams) (*DeleteResourceIconResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteResourceIcon", p)
	ret0, _ := ret[0].(*DeleteResourceIconResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListResourceIcon mocks base method.
func (m *MockResourceIconServiceIface) ListResourceIcon(p *ListResourceIconParams) (*ListResourceIconResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListResourceIcon", p)
	ret0, _ := ret[0].(*ListResourceIconResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewDeleteResourceIconParams mocks base method.
func (m *MockResourceIconServiceIface) NewDeleteResourceIconParams(resourceids []string, resourcetype string) *DeleteResourceIconParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteResourceIconParams", resourceids, resourcetype)
	ret0, _ := ret[0].(*DeleteResourceIconParams)
	return ret0
}

// NewDeleteResourceIconParams indicates an expected call of NewDeleteResourceIconParams.
func (mr *MockResourceIconServiceIfaceMockRecorder) NewDeleteResourceIconParams(resourceids, resourcetype any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteResourceIconParams", reflect.TypeOf((*MockResourceIconServiceIface)(nil).NewDeleteResourceIconParams), resourceids, resourcetype)
}

// NewListResourceIconParams mocks base method.
func (m *MockResourceIconServiceIface) NewListResourceIconParams(resourceids []string, resourcetype string) *ListResourceIconParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListResourceIconParams", resourceids, resourcetype)
	ret0, _ := ret[0].(*ListResourceIconParams)
	return ret0
}

// NewListResourceIconParams indicates an expected call of NewListResourceIconParams.
func (mr *MockResourceIconServiceIfaceMockRecorder) NewListResourceIconParams(resourceids, resourcetype any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListResourceIconParams", reflect.TypeOf((*MockResourceIconServiceIface)(nil).NewListResourceIconParams), resourceids, resourcetype)
}

// NewUploadResourceIconParams mocks base method.
func (m *MockResourceIconServiceIface) NewUploadResourceIconParams(base64image string, resourceids []string, resourcetype string) *UploadResourceIconParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUploadResourceIconParams", base64image, resourceids, resourcetype)
	ret0, _ := ret[0].(*UploadResourceIconParams)
	return ret0
}

// NewUploadResourceIconParams indicates an expected call of NewUploadResourceIconParams.
func (mr *MockResourceIconServiceIfaceMockRecorder) NewUploadResourceIconParams(base64image, resourceids, resourcetype any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUploadResourceIconParams", reflect.TypeOf((*MockResourceIconServiceIface)(nil).NewUploadResourceIconParams), base64image, resourceids, resourcetype)
}

// UploadResourceIcon mocks base method.
func (m *MockResourceIconServiceIface) UploadResourceIcon(p *UploadResourceIconParams) (*UploadResourceIconResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UploadResourceIcon", p)
	ret0, _ := ret[0].(*UploadResourceIconResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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