//
// 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

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

import (
	reflect "reflect"

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

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

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