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

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

import (
	reflect "reflect"

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

// MockNetworkACLServiceIface is a mock of NetworkACLServiceIface interface.
type MockNetworkACLServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockNetworkACLServiceIfaceMockRecorder
	isgomock struct{}
}

// MockNetworkACLServiceIfaceMockRecorder is the mock recorder for MockNetworkACLServiceIface.
type MockNetworkACLServiceIfaceMockRecorder struct {
	mock *MockNetworkACLServiceIface
}

// NewMockNetworkACLServiceIface creates a new mock instance.
func NewMockNetworkACLServiceIface(ctrl *gomock.Controller) *MockNetworkACLServiceIface {
	mock := &MockNetworkACLServiceIface{ctrl: ctrl}
	mock.recorder = &MockNetworkACLServiceIfaceMockRecorder{mock}
	return mock
}

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

// CreateNetworkACL mocks base method.
func (m *MockNetworkACLServiceIface) CreateNetworkACL(p *CreateNetworkACLParams) (*CreateNetworkACLResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateNetworkACL", p)
	ret0, _ := ret[0].(*CreateNetworkACLResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// CreateNetworkACLList mocks base method.
func (m *MockNetworkACLServiceIface) CreateNetworkACLList(p *CreateNetworkACLListParams) (*CreateNetworkACLListResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateNetworkACLList", p)
	ret0, _ := ret[0].(*CreateNetworkACLListResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteNetworkACL mocks base method.
func (m *MockNetworkACLServiceIface) DeleteNetworkACL(p *DeleteNetworkACLParams) (*DeleteNetworkACLResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteNetworkACL", p)
	ret0, _ := ret[0].(*DeleteNetworkACLResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteNetworkACLList mocks base method.
func (m *MockNetworkACLServiceIface) DeleteNetworkACLList(p *DeleteNetworkACLListParams) (*DeleteNetworkACLListResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteNetworkACLList", p)
	ret0, _ := ret[0].(*DeleteNetworkACLListResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

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

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

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

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

// ListNetworkACLLists mocks base method.
func (m *MockNetworkACLServiceIface) ListNetworkACLLists(p *ListNetworkACLListsParams) (*ListNetworkACLListsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListNetworkACLLists", p)
	ret0, _ := ret[0].(*ListNetworkACLListsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListNetworkACLs mocks base method.
func (m *MockNetworkACLServiceIface) ListNetworkACLs(p *ListNetworkACLsParams) (*ListNetworkACLsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListNetworkACLs", p)
	ret0, _ := ret[0].(*ListNetworkACLsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// MoveNetworkAclItem mocks base method.
func (m *MockNetworkACLServiceIface) MoveNetworkAclItem(p *MoveNetworkAclItemParams) (*MoveNetworkAclItemResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "MoveNetworkAclItem", p)
	ret0, _ := ret[0].(*MoveNetworkAclItemResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewCreateNetworkACLListParams mocks base method.
func (m *MockNetworkACLServiceIface) NewCreateNetworkACLListParams(name, vpcid string) *CreateNetworkACLListParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateNetworkACLListParams", name, vpcid)
	ret0, _ := ret[0].(*CreateNetworkACLListParams)
	return ret0
}

// NewCreateNetworkACLListParams indicates an expected call of NewCreateNetworkACLListParams.
func (mr *MockNetworkACLServiceIfaceMockRecorder) NewCreateNetworkACLListParams(name, vpcid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateNetworkACLListParams", reflect.TypeOf((*MockNetworkACLServiceIface)(nil).NewCreateNetworkACLListParams), name, vpcid)
}

// NewCreateNetworkACLParams mocks base method.
func (m *MockNetworkACLServiceIface) NewCreateNetworkACLParams(protocol string) *CreateNetworkACLParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateNetworkACLParams", protocol)
	ret0, _ := ret[0].(*CreateNetworkACLParams)
	return ret0
}

// NewCreateNetworkACLParams indicates an expected call of NewCreateNetworkACLParams.
func (mr *MockNetworkACLServiceIfaceMockRecorder) NewCreateNetworkACLParams(protocol any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateNetworkACLParams", reflect.TypeOf((*MockNetworkACLServiceIface)(nil).NewCreateNetworkACLParams), protocol)
}

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

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

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

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

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

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

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

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

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

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

// NewReplaceNetworkACLListParams mocks base method.
func (m *MockNetworkACLServiceIface) NewReplaceNetworkACLListParams(aclid string) *ReplaceNetworkACLListParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewReplaceNetworkACLListParams", aclid)
	ret0, _ := ret[0].(*ReplaceNetworkACLListParams)
	return ret0
}

// NewReplaceNetworkACLListParams indicates an expected call of NewReplaceNetworkACLListParams.
func (mr *MockNetworkACLServiceIfaceMockRecorder) NewReplaceNetworkACLListParams(aclid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewReplaceNetworkACLListParams", reflect.TypeOf((*MockNetworkACLServiceIface)(nil).NewReplaceNetworkACLListParams), aclid)
}

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

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

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

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

// ReplaceNetworkACLList mocks base method.
func (m *MockNetworkACLServiceIface) ReplaceNetworkACLList(p *ReplaceNetworkACLListParams) (*ReplaceNetworkACLListResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ReplaceNetworkACLList", p)
	ret0, _ := ret[0].(*ReplaceNetworkACLListResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateNetworkACLItem mocks base method.
func (m *MockNetworkACLServiceIface) UpdateNetworkACLItem(p *UpdateNetworkACLItemParams) (*UpdateNetworkACLItemResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateNetworkACLItem", p)
	ret0, _ := ret[0].(*UpdateNetworkACLItemResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateNetworkACLList mocks base method.
func (m *MockNetworkACLServiceIface) UpdateNetworkACLList(p *UpdateNetworkACLListParams) (*UpdateNetworkACLListResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateNetworkACLList", p)
	ret0, _ := ret[0].(*UpdateNetworkACLListResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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