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

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

import (
	reflect "reflect"

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

// MockAuthenticationServiceIface is a mock of AuthenticationServiceIface interface.
type MockAuthenticationServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockAuthenticationServiceIfaceMockRecorder
	isgomock struct{}
}

// MockAuthenticationServiceIfaceMockRecorder is the mock recorder for MockAuthenticationServiceIface.
type MockAuthenticationServiceIfaceMockRecorder struct {
	mock *MockAuthenticationServiceIface
}

// NewMockAuthenticationServiceIface creates a new mock instance.
func NewMockAuthenticationServiceIface(ctrl *gomock.Controller) *MockAuthenticationServiceIface {
	mock := &MockAuthenticationServiceIface{ctrl: ctrl}
	mock.recorder = &MockAuthenticationServiceIfaceMockRecorder{mock}
	return mock
}

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

// Login mocks base method.
func (m *MockAuthenticationServiceIface) Login(p *LoginParams) (*LoginResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Login", p)
	ret0, _ := ret[0].(*LoginResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// Logout mocks base method.
func (m *MockAuthenticationServiceIface) Logout(p *LogoutParams) (*LogoutResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Logout", p)
	ret0, _ := ret[0].(*LogoutResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

// NewOauthloginParams mocks base method.
func (m *MockAuthenticationServiceIface) NewOauthloginParams(email, provider string) *OauthloginParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewOauthloginParams", email, provider)
	ret0, _ := ret[0].(*OauthloginParams)
	return ret0
}

// NewOauthloginParams indicates an expected call of NewOauthloginParams.
func (mr *MockAuthenticationServiceIfaceMockRecorder) NewOauthloginParams(email, provider any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewOauthloginParams", reflect.TypeOf((*MockAuthenticationServiceIface)(nil).NewOauthloginParams), email, provider)
}

// Oauthlogin mocks base method.
func (m *MockAuthenticationServiceIface) Oauthlogin(p *OauthloginParams) (*OauthloginResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Oauthlogin", p)
	ret0, _ := ret[0].(*OauthloginResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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