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

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

import (
	reflect "reflect"

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

// MockDomainServiceIface is a mock of DomainServiceIface interface.
type MockDomainServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockDomainServiceIfaceMockRecorder
}

// MockDomainServiceIfaceMockRecorder is the mock recorder for MockDomainServiceIface.
type MockDomainServiceIfaceMockRecorder struct {
	mock *MockDomainServiceIface
}

// NewMockDomainServiceIface creates a new mock instance.
func NewMockDomainServiceIface(ctrl *gomock.Controller) *MockDomainServiceIface {
	mock := &MockDomainServiceIface{ctrl: ctrl}
	mock.recorder = &MockDomainServiceIfaceMockRecorder{mock}
	return mock
}

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

// CreateDomain mocks base method.
func (m *MockDomainServiceIface) CreateDomain(p *CreateDomainParams) (*CreateDomainResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateDomain", p)
	ret0, _ := ret[0].(*CreateDomainResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteDomain mocks base method.
func (m *MockDomainServiceIface) DeleteDomain(p *DeleteDomainParams) (*DeleteDomainResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteDomain", p)
	ret0, _ := ret[0].(*DeleteDomainResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

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

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

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

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

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

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

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

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

// ListDomainChildren mocks base method.
func (m *MockDomainServiceIface) ListDomainChildren(p *ListDomainChildrenParams) (*ListDomainChildrenResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListDomainChildren", p)
	ret0, _ := ret[0].(*ListDomainChildrenResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListDomains mocks base method.
func (m *MockDomainServiceIface) ListDomains(p *ListDomainsParams) (*ListDomainsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListDomains", p)
	ret0, _ := ret[0].(*ListDomainsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

// NewCreateDomainParams indicates an expected call of NewCreateDomainParams.
func (mr *MockDomainServiceIfaceMockRecorder) NewCreateDomainParams(name interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateDomainParams", reflect.TypeOf((*MockDomainServiceIface)(nil).NewCreateDomainParams), name)
}

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

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

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

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

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

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

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

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

// UpdateDomain mocks base method.
func (m *MockDomainServiceIface) UpdateDomain(p *UpdateDomainParams) (*UpdateDomainResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateDomain", p)
	ret0, _ := ret[0].(*UpdateDomainResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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