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

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

import (
	reflect "reflect"

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

// MockManagementServiceIface is a mock of ManagementServiceIface interface.
type MockManagementServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockManagementServiceIfaceMockRecorder
	isgomock struct{}
}

// MockManagementServiceIfaceMockRecorder is the mock recorder for MockManagementServiceIface.
type MockManagementServiceIfaceMockRecorder struct {
	mock *MockManagementServiceIface
}

// NewMockManagementServiceIface creates a new mock instance.
func NewMockManagementServiceIface(ctrl *gomock.Controller) *MockManagementServiceIface {
	mock := &MockManagementServiceIface{ctrl: ctrl}
	mock.recorder = &MockManagementServiceIfaceMockRecorder{mock}
	return mock
}

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

// CancelShutdown mocks base method.
func (m *MockManagementServiceIface) CancelShutdown(p *CancelShutdownParams) (*CancelShutdownResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CancelShutdown", p)
	ret0, _ := ret[0].(*CancelShutdownResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

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

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

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

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

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

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

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

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

// ListManagementServers mocks base method.
func (m *MockManagementServiceIface) ListManagementServers(p *ListManagementServersParams) (*ListManagementServersResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListManagementServers", p)
	ret0, _ := ret[0].(*ListManagementServersResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListManagementServersMetrics mocks base method.
func (m *MockManagementServiceIface) ListManagementServersMetrics(p *ListManagementServersMetricsParams) (*ListManagementServersMetricsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListManagementServersMetrics", p)
	ret0, _ := ret[0].(*ListManagementServersMetricsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewCancelShutdownParams mocks base method.
func (m *MockManagementServiceIface) NewCancelShutdownParams(managementserverid UUID) *CancelShutdownParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCancelShutdownParams", managementserverid)
	ret0, _ := ret[0].(*CancelShutdownParams)
	return ret0
}

// NewCancelShutdownParams indicates an expected call of NewCancelShutdownParams.
func (mr *MockManagementServiceIfaceMockRecorder) NewCancelShutdownParams(managementserverid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCancelShutdownParams", reflect.TypeOf((*MockManagementServiceIface)(nil).NewCancelShutdownParams), managementserverid)
}

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

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

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

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

// NewPrepareForShutdownParams mocks base method.
func (m *MockManagementServiceIface) NewPrepareForShutdownParams(managementserverid UUID) *PrepareForShutdownParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewPrepareForShutdownParams", managementserverid)
	ret0, _ := ret[0].(*PrepareForShutdownParams)
	return ret0
}

// NewPrepareForShutdownParams indicates an expected call of NewPrepareForShutdownParams.
func (mr *MockManagementServiceIfaceMockRecorder) NewPrepareForShutdownParams(managementserverid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewPrepareForShutdownParams", reflect.TypeOf((*MockManagementServiceIface)(nil).NewPrepareForShutdownParams), managementserverid)
}

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

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

// NewTriggerShutdownParams mocks base method.
func (m *MockManagementServiceIface) NewTriggerShutdownParams(managementserverid UUID) *TriggerShutdownParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewTriggerShutdownParams", managementserverid)
	ret0, _ := ret[0].(*TriggerShutdownParams)
	return ret0
}

// NewTriggerShutdownParams indicates an expected call of NewTriggerShutdownParams.
func (mr *MockManagementServiceIfaceMockRecorder) NewTriggerShutdownParams(managementserverid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewTriggerShutdownParams", reflect.TypeOf((*MockManagementServiceIface)(nil).NewTriggerShutdownParams), managementserverid)
}

// PrepareForShutdown mocks base method.
func (m *MockManagementServiceIface) PrepareForShutdown(p *PrepareForShutdownParams) (*PrepareForShutdownResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "PrepareForShutdown", p)
	ret0, _ := ret[0].(*PrepareForShutdownResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ReadyForShutdown mocks base method.
func (m *MockManagementServiceIface) ReadyForShutdown(p *ReadyForShutdownParams) (*ReadyForShutdownResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ReadyForShutdown", p)
	ret0, _ := ret[0].(*ReadyForShutdownResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// TriggerShutdown mocks base method.
func (m *MockManagementServiceIface) TriggerShutdown(p *TriggerShutdownParams) (*TriggerShutdownResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "TriggerShutdown", p)
	ret0, _ := ret[0].(*TriggerShutdownResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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