//
// 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/NetworkOfferingService.go

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

import (
	reflect "reflect"

	gomock "github.com/golang/mock/gomock"
)

// MockNetworkOfferingServiceIface is a mock of NetworkOfferingServiceIface interface.
type MockNetworkOfferingServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockNetworkOfferingServiceIfaceMockRecorder
}

// MockNetworkOfferingServiceIfaceMockRecorder is the mock recorder for MockNetworkOfferingServiceIface.
type MockNetworkOfferingServiceIfaceMockRecorder struct {
	mock *MockNetworkOfferingServiceIface
}

// NewMockNetworkOfferingServiceIface creates a new mock instance.
func NewMockNetworkOfferingServiceIface(ctrl *gomock.Controller) *MockNetworkOfferingServiceIface {
	mock := &MockNetworkOfferingServiceIface{ctrl: ctrl}
	mock.recorder = &MockNetworkOfferingServiceIfaceMockRecorder{mock}
	return mock
}

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

// CreateNetworkOffering mocks base method.
func (m *MockNetworkOfferingServiceIface) CreateNetworkOffering(p *CreateNetworkOfferingParams) (*CreateNetworkOfferingResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateNetworkOffering", p)
	ret0, _ := ret[0].(*CreateNetworkOfferingResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateNetworkOffering indicates an expected call of CreateNetworkOffering.
func (mr *MockNetworkOfferingServiceIfaceMockRecorder) CreateNetworkOffering(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNetworkOffering", reflect.TypeOf((*MockNetworkOfferingServiceIface)(nil).CreateNetworkOffering), p)
}

// DeleteNetworkOffering mocks base method.
func (m *MockNetworkOfferingServiceIface) DeleteNetworkOffering(p *DeleteNetworkOfferingParams) (*DeleteNetworkOfferingResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteNetworkOffering", p)
	ret0, _ := ret[0].(*DeleteNetworkOfferingResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteNetworkOffering indicates an expected call of DeleteNetworkOffering.
func (mr *MockNetworkOfferingServiceIfaceMockRecorder) DeleteNetworkOffering(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteNetworkOffering", reflect.TypeOf((*MockNetworkOfferingServiceIface)(nil).DeleteNetworkOffering), p)
}

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

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

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

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

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

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

// ListNetworkOfferings mocks base method.
func (m *MockNetworkOfferingServiceIface) ListNetworkOfferings(p *ListNetworkOfferingsParams) (*ListNetworkOfferingsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListNetworkOfferings", p)
	ret0, _ := ret[0].(*ListNetworkOfferingsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListNetworkOfferings indicates an expected call of ListNetworkOfferings.
func (mr *MockNetworkOfferingServiceIfaceMockRecorder) ListNetworkOfferings(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListNetworkOfferings", reflect.TypeOf((*MockNetworkOfferingServiceIface)(nil).ListNetworkOfferings), p)
}

// NewCreateNetworkOfferingParams mocks base method.
func (m *MockNetworkOfferingServiceIface) NewCreateNetworkOfferingParams(displaytext, guestiptype, name, traffictype string) *CreateNetworkOfferingParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewCreateNetworkOfferingParams", displaytext, guestiptype, name, traffictype)
	ret0, _ := ret[0].(*CreateNetworkOfferingParams)
	return ret0
}

// NewCreateNetworkOfferingParams indicates an expected call of NewCreateNetworkOfferingParams.
func (mr *MockNetworkOfferingServiceIfaceMockRecorder) NewCreateNetworkOfferingParams(displaytext, guestiptype, name, traffictype interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateNetworkOfferingParams", reflect.TypeOf((*MockNetworkOfferingServiceIface)(nil).NewCreateNetworkOfferingParams), displaytext, guestiptype, name, traffictype)
}

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

// NewDeleteNetworkOfferingParams indicates an expected call of NewDeleteNetworkOfferingParams.
func (mr *MockNetworkOfferingServiceIfaceMockRecorder) NewDeleteNetworkOfferingParams(id interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteNetworkOfferingParams", reflect.TypeOf((*MockNetworkOfferingServiceIface)(nil).NewDeleteNetworkOfferingParams), id)
}

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

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

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

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

// UpdateNetworkOffering mocks base method.
func (m *MockNetworkOfferingServiceIface) UpdateNetworkOffering(p *UpdateNetworkOfferingParams) (*UpdateNetworkOfferingResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateNetworkOffering", p)
	ret0, _ := ret[0].(*UpdateNetworkOfferingResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateNetworkOffering indicates an expected call of UpdateNetworkOffering.
func (mr *MockNetworkOfferingServiceIfaceMockRecorder) UpdateNetworkOffering(p interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateNetworkOffering", reflect.TypeOf((*MockNetworkOfferingServiceIface)(nil).UpdateNetworkOffering), p)
}
