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

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

import (
	reflect "reflect"

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

// MockLDAPServiceIface is a mock of LDAPServiceIface interface.
type MockLDAPServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockLDAPServiceIfaceMockRecorder
	isgomock struct{}
}

// MockLDAPServiceIfaceMockRecorder is the mock recorder for MockLDAPServiceIface.
type MockLDAPServiceIfaceMockRecorder struct {
	mock *MockLDAPServiceIface
}

// NewMockLDAPServiceIface creates a new mock instance.
func NewMockLDAPServiceIface(ctrl *gomock.Controller) *MockLDAPServiceIface {
	mock := &MockLDAPServiceIface{ctrl: ctrl}
	mock.recorder = &MockLDAPServiceIfaceMockRecorder{mock}
	return mock
}

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

// AddLdapConfiguration mocks base method.
func (m *MockLDAPServiceIface) AddLdapConfiguration(p *AddLdapConfigurationParams) (*AddLdapConfigurationResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddLdapConfiguration", p)
	ret0, _ := ret[0].(*AddLdapConfigurationResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteLdapConfiguration mocks base method.
func (m *MockLDAPServiceIface) DeleteLdapConfiguration(p *DeleteLdapConfigurationParams) (*DeleteLdapConfigurationResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteLdapConfiguration", p)
	ret0, _ := ret[0].(*DeleteLdapConfigurationResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ImportLdapUsers mocks base method.
func (m *MockLDAPServiceIface) ImportLdapUsers(p *ImportLdapUsersParams) (*ImportLdapUsersResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ImportLdapUsers", p)
	ret0, _ := ret[0].(*ImportLdapUsersResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// LdapConfig mocks base method.
func (m *MockLDAPServiceIface) LdapConfig(p *LdapConfigParams) (*LdapConfigResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LdapConfig", p)
	ret0, _ := ret[0].(*LdapConfigResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// LdapCreateAccount mocks base method.
func (m *MockLDAPServiceIface) LdapCreateAccount(p *LdapCreateAccountParams) (*LdapCreateAccountResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LdapCreateAccount", p)
	ret0, _ := ret[0].(*LdapCreateAccountResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// LdapRemove mocks base method.
func (m *MockLDAPServiceIface) LdapRemove(p *LdapRemoveParams) (*LdapRemoveResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LdapRemove", p)
	ret0, _ := ret[0].(*LdapRemoveResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// LinkDomainToLdap mocks base method.
func (m *MockLDAPServiceIface) LinkDomainToLdap(p *LinkDomainToLdapParams) (*LinkDomainToLdapResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LinkDomainToLdap", p)
	ret0, _ := ret[0].(*LinkDomainToLdapResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListLdapConfigurations mocks base method.
func (m *MockLDAPServiceIface) ListLdapConfigurations(p *ListLdapConfigurationsParams) (*ListLdapConfigurationsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListLdapConfigurations", p)
	ret0, _ := ret[0].(*ListLdapConfigurationsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListLdapUsers mocks base method.
func (m *MockLDAPServiceIface) ListLdapUsers(p *ListLdapUsersParams) (*ListLdapUsersResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListLdapUsers", p)
	ret0, _ := ret[0].(*ListLdapUsersResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewAddLdapConfigurationParams mocks base method.
func (m *MockLDAPServiceIface) NewAddLdapConfigurationParams(hostname string, port int) *AddLdapConfigurationParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddLdapConfigurationParams", hostname, port)
	ret0, _ := ret[0].(*AddLdapConfigurationParams)
	return ret0
}

// NewAddLdapConfigurationParams indicates an expected call of NewAddLdapConfigurationParams.
func (mr *MockLDAPServiceIfaceMockRecorder) NewAddLdapConfigurationParams(hostname, port any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddLdapConfigurationParams", reflect.TypeOf((*MockLDAPServiceIface)(nil).NewAddLdapConfigurationParams), hostname, port)
}

// NewDeleteLdapConfigurationParams mocks base method.
func (m *MockLDAPServiceIface) NewDeleteLdapConfigurationParams(hostname string) *DeleteLdapConfigurationParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteLdapConfigurationParams", hostname)
	ret0, _ := ret[0].(*DeleteLdapConfigurationParams)
	return ret0
}

// NewDeleteLdapConfigurationParams indicates an expected call of NewDeleteLdapConfigurationParams.
func (mr *MockLDAPServiceIfaceMockRecorder) NewDeleteLdapConfigurationParams(hostname any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteLdapConfigurationParams", reflect.TypeOf((*MockLDAPServiceIface)(nil).NewDeleteLdapConfigurationParams), hostname)
}

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

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

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

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

// NewLdapCreateAccountParams mocks base method.
func (m *MockLDAPServiceIface) NewLdapCreateAccountParams(username string) *LdapCreateAccountParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewLdapCreateAccountParams", username)
	ret0, _ := ret[0].(*LdapCreateAccountParams)
	return ret0
}

// NewLdapCreateAccountParams indicates an expected call of NewLdapCreateAccountParams.
func (mr *MockLDAPServiceIfaceMockRecorder) NewLdapCreateAccountParams(username any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewLdapCreateAccountParams", reflect.TypeOf((*MockLDAPServiceIface)(nil).NewLdapCreateAccountParams), username)
}

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

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

// NewLinkDomainToLdapParams mocks base method.
func (m *MockLDAPServiceIface) NewLinkDomainToLdapParams(accounttype int, domainid, lDAPType string) *LinkDomainToLdapParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewLinkDomainToLdapParams", accounttype, domainid, lDAPType)
	ret0, _ := ret[0].(*LinkDomainToLdapParams)
	return ret0
}

// NewLinkDomainToLdapParams indicates an expected call of NewLinkDomainToLdapParams.
func (mr *MockLDAPServiceIfaceMockRecorder) NewLinkDomainToLdapParams(accounttype, domainid, lDAPType any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewLinkDomainToLdapParams", reflect.TypeOf((*MockLDAPServiceIface)(nil).NewLinkDomainToLdapParams), accounttype, domainid, lDAPType)
}

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

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

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

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

// NewSearchLdapParams mocks base method.
func (m *MockLDAPServiceIface) NewSearchLdapParams(query string) *SearchLdapParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewSearchLdapParams", query)
	ret0, _ := ret[0].(*SearchLdapParams)
	return ret0
}

// NewSearchLdapParams indicates an expected call of NewSearchLdapParams.
func (mr *MockLDAPServiceIfaceMockRecorder) NewSearchLdapParams(query any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewSearchLdapParams", reflect.TypeOf((*MockLDAPServiceIface)(nil).NewSearchLdapParams), query)
}

// SearchLdap mocks base method.
func (m *MockLDAPServiceIface) SearchLdap(p *SearchLdapParams) (*SearchLdapResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "SearchLdap", p)
	ret0, _ := ret[0].(*SearchLdapResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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