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

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

import (
	reflect "reflect"

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

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

// 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 any) *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 any) *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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 := []any{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 any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{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 any) *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 any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDomains", reflect.TypeOf((*MockDomainServiceIface)(nil).ListDomains), p)
}

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

// MoveDomain indicates an expected call of MoveDomain.
func (mr *MockDomainServiceIfaceMockRecorder) MoveDomain(p any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MoveDomain", reflect.TypeOf((*MockDomainServiceIface)(nil).MoveDomain), 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 any) *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 any) *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))
}

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

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

// 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 any) *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 any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDomain", reflect.TypeOf((*MockDomainServiceIface)(nil).UpdateDomain), p)
}
