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

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

import (
	reflect "reflect"

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

// MockRegionServiceIface is a mock of RegionServiceIface interface.
type MockRegionServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockRegionServiceIfaceMockRecorder
	isgomock struct{}
}

// MockRegionServiceIfaceMockRecorder is the mock recorder for MockRegionServiceIface.
type MockRegionServiceIfaceMockRecorder struct {
	mock *MockRegionServiceIface
}

// NewMockRegionServiceIface creates a new mock instance.
func NewMockRegionServiceIface(ctrl *gomock.Controller) *MockRegionServiceIface {
	mock := &MockRegionServiceIface{ctrl: ctrl}
	mock.recorder = &MockRegionServiceIfaceMockRecorder{mock}
	return mock
}

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

// AddRegion mocks base method.
func (m *MockRegionServiceIface) AddRegion(p *AddRegionParams) (*AddRegionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddRegion", p)
	ret0, _ := ret[0].(*AddRegionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListRegions mocks base method.
func (m *MockRegionServiceIface) ListRegions(p *ListRegionsParams) (*ListRegionsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListRegions", p)
	ret0, _ := ret[0].(*ListRegionsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewAddRegionParams mocks base method.
func (m *MockRegionServiceIface) NewAddRegionParams(endpoint string, id int, name string) *AddRegionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddRegionParams", endpoint, id, name)
	ret0, _ := ret[0].(*AddRegionParams)
	return ret0
}

// NewAddRegionParams indicates an expected call of NewAddRegionParams.
func (mr *MockRegionServiceIfaceMockRecorder) NewAddRegionParams(endpoint, id, name any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddRegionParams", reflect.TypeOf((*MockRegionServiceIface)(nil).NewAddRegionParams), endpoint, id, name)
}

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

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

// NewRemoveRegionParams mocks base method.
func (m *MockRegionServiceIface) NewRemoveRegionParams(id int) *RemoveRegionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewRemoveRegionParams", id)
	ret0, _ := ret[0].(*RemoveRegionParams)
	return ret0
}

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

// NewUpdateRegionParams mocks base method.
func (m *MockRegionServiceIface) NewUpdateRegionParams(id int) *UpdateRegionParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateRegionParams", id)
	ret0, _ := ret[0].(*UpdateRegionParams)
	return ret0
}

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

// RemoveRegion mocks base method.
func (m *MockRegionServiceIface) RemoveRegion(p *RemoveRegionParams) (*RemoveRegionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RemoveRegion", p)
	ret0, _ := ret[0].(*RemoveRegionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateRegion mocks base method.
func (m *MockRegionServiceIface) UpdateRegion(p *UpdateRegionParams) (*UpdateRegionResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateRegion", p)
	ret0, _ := ret[0].(*UpdateRegionResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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