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

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

import (
	reflect "reflect"

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

// MockPodServiceIface is a mock of PodServiceIface interface.
type MockPodServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockPodServiceIfaceMockRecorder
	isgomock struct{}
}

// MockPodServiceIfaceMockRecorder is the mock recorder for MockPodServiceIface.
type MockPodServiceIfaceMockRecorder struct {
	mock *MockPodServiceIface
}

// NewMockPodServiceIface creates a new mock instance.
func NewMockPodServiceIface(ctrl *gomock.Controller) *MockPodServiceIface {
	mock := &MockPodServiceIface{ctrl: ctrl}
	mock.recorder = &MockPodServiceIfaceMockRecorder{mock}
	return mock
}

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

// CreateManagementNetworkIpRange mocks base method.
func (m *MockPodServiceIface) CreateManagementNetworkIpRange(p *CreateManagementNetworkIpRangeParams) (*CreateManagementNetworkIpRangeResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateManagementNetworkIpRange", p)
	ret0, _ := ret[0].(*CreateManagementNetworkIpRangeResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreatePod mocks base method.
func (m *MockPodServiceIface) CreatePod(p *CreatePodParams) (*CreatePodResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreatePod", p)
	ret0, _ := ret[0].(*CreatePodResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DedicatePod mocks base method.
func (m *MockPodServiceIface) DedicatePod(p *DedicatePodParams) (*DedicatePodResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DedicatePod", p)
	ret0, _ := ret[0].(*DedicatePodResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteManagementNetworkIpRange mocks base method.
func (m *MockPodServiceIface) DeleteManagementNetworkIpRange(p *DeleteManagementNetworkIpRangeParams) (*DeleteManagementNetworkIpRangeResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteManagementNetworkIpRange", p)
	ret0, _ := ret[0].(*DeleteManagementNetworkIpRangeResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeletePod mocks base method.
func (m *MockPodServiceIface) DeletePod(p *DeletePodParams) (*DeletePodResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeletePod", p)
	ret0, _ := ret[0].(*DeletePodResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

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

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

// ListDedicatedPods mocks base method.
func (m *MockPodServiceIface) ListDedicatedPods(p *ListDedicatedPodsParams) (*ListDedicatedPodsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListDedicatedPods", p)
	ret0, _ := ret[0].(*ListDedicatedPodsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListPods mocks base method.
func (m *MockPodServiceIface) ListPods(p *ListPodsParams) (*ListPodsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListPods", p)
	ret0, _ := ret[0].(*ListPodsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewCreateManagementNetworkIpRangeParams mocks base method.
func (m *MockPodServiceIface) NewCreateManagementNetworkIpRangeParams(gateway, netmask, podid, startip string) *CreateManagementNetworkIpRangeParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateManagementNetworkIpRangeParams", gateway, netmask, podid, startip)
	ret0, _ := ret[0].(*CreateManagementNetworkIpRangeParams)
	return ret0
}

// NewCreateManagementNetworkIpRangeParams indicates an expected call of NewCreateManagementNetworkIpRangeParams.
func (mr *MockPodServiceIfaceMockRecorder) NewCreateManagementNetworkIpRangeParams(gateway, netmask, podid, startip any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateManagementNetworkIpRangeParams", reflect.TypeOf((*MockPodServiceIface)(nil).NewCreateManagementNetworkIpRangeParams), gateway, netmask, podid, startip)
}

// NewCreatePodParams mocks base method.
func (m *MockPodServiceIface) NewCreatePodParams(name, zoneid string) *CreatePodParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreatePodParams", name, zoneid)
	ret0, _ := ret[0].(*CreatePodParams)
	return ret0
}

// NewCreatePodParams indicates an expected call of NewCreatePodParams.
func (mr *MockPodServiceIfaceMockRecorder) NewCreatePodParams(name, zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreatePodParams", reflect.TypeOf((*MockPodServiceIface)(nil).NewCreatePodParams), name, zoneid)
}

// NewDedicatePodParams mocks base method.
func (m *MockPodServiceIface) NewDedicatePodParams(domainid, podid string) *DedicatePodParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDedicatePodParams", domainid, podid)
	ret0, _ := ret[0].(*DedicatePodParams)
	return ret0
}

// NewDedicatePodParams indicates an expected call of NewDedicatePodParams.
func (mr *MockPodServiceIfaceMockRecorder) NewDedicatePodParams(domainid, podid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDedicatePodParams", reflect.TypeOf((*MockPodServiceIface)(nil).NewDedicatePodParams), domainid, podid)
}

// NewDeleteManagementNetworkIpRangeParams mocks base method.
func (m *MockPodServiceIface) NewDeleteManagementNetworkIpRangeParams(endip, podid, startip, vlan string) *DeleteManagementNetworkIpRangeParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteManagementNetworkIpRangeParams", endip, podid, startip, vlan)
	ret0, _ := ret[0].(*DeleteManagementNetworkIpRangeParams)
	return ret0
}

// NewDeleteManagementNetworkIpRangeParams indicates an expected call of NewDeleteManagementNetworkIpRangeParams.
func (mr *MockPodServiceIfaceMockRecorder) NewDeleteManagementNetworkIpRangeParams(endip, podid, startip, vlan any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteManagementNetworkIpRangeParams", reflect.TypeOf((*MockPodServiceIface)(nil).NewDeleteManagementNetworkIpRangeParams), endip, podid, startip, vlan)
}

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

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

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

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

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

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

// NewReleaseDedicatedPodParams mocks base method.
func (m *MockPodServiceIface) NewReleaseDedicatedPodParams(podid string) *ReleaseDedicatedPodParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewReleaseDedicatedPodParams", podid)
	ret0, _ := ret[0].(*ReleaseDedicatedPodParams)
	return ret0
}

// NewReleaseDedicatedPodParams indicates an expected call of NewReleaseDedicatedPodParams.
func (mr *MockPodServiceIfaceMockRecorder) NewReleaseDedicatedPodParams(podid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewReleaseDedicatedPodParams", reflect.TypeOf((*MockPodServiceIface)(nil).NewReleaseDedicatedPodParams), podid)
}

// NewUpdatePodManagementNetworkIpRangeParams mocks base method.
func (m *MockPodServiceIface) NewUpdatePodManagementNetworkIpRangeParams(currentendip, currentstartip, podid string) *UpdatePodManagementNetworkIpRangeParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdatePodManagementNetworkIpRangeParams", currentendip, currentstartip, podid)
	ret0, _ := ret[0].(*UpdatePodManagementNetworkIpRangeParams)
	return ret0
}

// NewUpdatePodManagementNetworkIpRangeParams indicates an expected call of NewUpdatePodManagementNetworkIpRangeParams.
func (mr *MockPodServiceIfaceMockRecorder) NewUpdatePodManagementNetworkIpRangeParams(currentendip, currentstartip, podid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdatePodManagementNetworkIpRangeParams", reflect.TypeOf((*MockPodServiceIface)(nil).NewUpdatePodManagementNetworkIpRangeParams), currentendip, currentstartip, podid)
}

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

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

// ReleaseDedicatedPod mocks base method.
func (m *MockPodServiceIface) ReleaseDedicatedPod(p *ReleaseDedicatedPodParams) (*ReleaseDedicatedPodResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ReleaseDedicatedPod", p)
	ret0, _ := ret[0].(*ReleaseDedicatedPodResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdatePod mocks base method.
func (m *MockPodServiceIface) UpdatePod(p *UpdatePodParams) (*UpdatePodResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdatePod", p)
	ret0, _ := ret[0].(*UpdatePodResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdatePodManagementNetworkIpRange mocks base method.
func (m *MockPodServiceIface) UpdatePodManagementNetworkIpRange(p *UpdatePodManagementNetworkIpRangeParams) (*UpdatePodManagementNetworkIpRangeResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdatePodManagementNetworkIpRange", p)
	ret0, _ := ret[0].(*UpdatePodManagementNetworkIpRangeResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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