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

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

import (
	reflect "reflect"

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

// MockRouterServiceIface is a mock of RouterServiceIface interface.
type MockRouterServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockRouterServiceIfaceMockRecorder
	isgomock struct{}
}

// MockRouterServiceIfaceMockRecorder is the mock recorder for MockRouterServiceIface.
type MockRouterServiceIfaceMockRecorder struct {
	mock *MockRouterServiceIface
}

// NewMockRouterServiceIface creates a new mock instance.
func NewMockRouterServiceIface(ctrl *gomock.Controller) *MockRouterServiceIface {
	mock := &MockRouterServiceIface{ctrl: ctrl}
	mock.recorder = &MockRouterServiceIfaceMockRecorder{mock}
	return mock
}

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

// ChangeServiceForRouter mocks base method.
func (m *MockRouterServiceIface) ChangeServiceForRouter(p *ChangeServiceForRouterParams) (*ChangeServiceForRouterResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ChangeServiceForRouter", p)
	ret0, _ := ret[0].(*ChangeServiceForRouterResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ConfigureVirtualRouterElement mocks base method.
func (m *MockRouterServiceIface) ConfigureVirtualRouterElement(p *ConfigureVirtualRouterElementParams) (*VirtualRouterElementResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ConfigureVirtualRouterElement", p)
	ret0, _ := ret[0].(*VirtualRouterElementResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreateVirtualRouterElement mocks base method.
func (m *MockRouterServiceIface) CreateVirtualRouterElement(p *CreateVirtualRouterElementParams) (*CreateVirtualRouterElementResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateVirtualRouterElement", p)
	ret0, _ := ret[0].(*CreateVirtualRouterElementResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DestroyRouter mocks base method.
func (m *MockRouterServiceIface) DestroyRouter(p *DestroyRouterParams) (*DestroyRouterResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DestroyRouter", p)
	ret0, _ := ret[0].(*DestroyRouterResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

// GetRouterHealthCheckResults mocks base method.
func (m *MockRouterServiceIface) GetRouterHealthCheckResults(p *GetRouterHealthCheckResultsParams) (*GetRouterHealthCheckResultsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetRouterHealthCheckResults", p)
	ret0, _ := ret[0].(*GetRouterHealthCheckResultsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// GetRouterID mocks base method.
func (m *MockRouterServiceIface) GetRouterID(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, "GetRouterID", varargs...)
	ret0, _ := ret[0].(string)
	ret1, _ := ret[1].(int)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

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

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

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

// ListRouters mocks base method.
func (m *MockRouterServiceIface) ListRouters(p *ListRoutersParams) (*ListRoutersResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListRouters", p)
	ret0, _ := ret[0].(*ListRoutersResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListVirtualRouterElements mocks base method.
func (m *MockRouterServiceIface) ListVirtualRouterElements(p *ListVirtualRouterElementsParams) (*ListVirtualRouterElementsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListVirtualRouterElements", p)
	ret0, _ := ret[0].(*ListVirtualRouterElementsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

// NewConfigureVirtualRouterElementParams mocks base method.
func (m *MockRouterServiceIface) NewConfigureVirtualRouterElementParams(enabled bool, id string) *ConfigureVirtualRouterElementParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewConfigureVirtualRouterElementParams", enabled, id)
	ret0, _ := ret[0].(*ConfigureVirtualRouterElementParams)
	return ret0
}

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

// NewCreateVirtualRouterElementParams mocks base method.
func (m *MockRouterServiceIface) NewCreateVirtualRouterElementParams(nspid string) *CreateVirtualRouterElementParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateVirtualRouterElementParams", nspid)
	ret0, _ := ret[0].(*CreateVirtualRouterElementParams)
	return ret0
}

// NewCreateVirtualRouterElementParams indicates an expected call of NewCreateVirtualRouterElementParams.
func (mr *MockRouterServiceIfaceMockRecorder) NewCreateVirtualRouterElementParams(nspid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateVirtualRouterElementParams", reflect.TypeOf((*MockRouterServiceIface)(nil).NewCreateVirtualRouterElementParams), nspid)
}

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

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

// NewGetRouterHealthCheckResultsParams mocks base method.
func (m *MockRouterServiceIface) NewGetRouterHealthCheckResultsParams(routerid string) *GetRouterHealthCheckResultsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewGetRouterHealthCheckResultsParams", routerid)
	ret0, _ := ret[0].(*GetRouterHealthCheckResultsParams)
	return ret0
}

// NewGetRouterHealthCheckResultsParams indicates an expected call of NewGetRouterHealthCheckResultsParams.
func (mr *MockRouterServiceIfaceMockRecorder) NewGetRouterHealthCheckResultsParams(routerid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewGetRouterHealthCheckResultsParams", reflect.TypeOf((*MockRouterServiceIface)(nil).NewGetRouterHealthCheckResultsParams), routerid)
}

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

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

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

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

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

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

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

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

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

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

// RebootRouter mocks base method.
func (m *MockRouterServiceIface) RebootRouter(p *RebootRouterParams) (*RebootRouterResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RebootRouter", p)
	ret0, _ := ret[0].(*RebootRouterResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// StartRouter mocks base method.
func (m *MockRouterServiceIface) StartRouter(p *StartRouterParams) (*StartRouterResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "StartRouter", p)
	ret0, _ := ret[0].(*StartRouterResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// StopRouter mocks base method.
func (m *MockRouterServiceIface) StopRouter(p *StopRouterParams) (*StopRouterResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "StopRouter", p)
	ret0, _ := ret[0].(*StopRouterResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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