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

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

import (
	reflect "reflect"

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

// MockEventServiceIface is a mock of EventServiceIface interface.
type MockEventServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockEventServiceIfaceMockRecorder
	isgomock struct{}
}

// MockEventServiceIfaceMockRecorder is the mock recorder for MockEventServiceIface.
type MockEventServiceIfaceMockRecorder struct {
	mock *MockEventServiceIface
}

// NewMockEventServiceIface creates a new mock instance.
func NewMockEventServiceIface(ctrl *gomock.Controller) *MockEventServiceIface {
	mock := &MockEventServiceIface{ctrl: ctrl}
	mock.recorder = &MockEventServiceIfaceMockRecorder{mock}
	return mock
}

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

// ArchiveEvents mocks base method.
func (m *MockEventServiceIface) ArchiveEvents(p *ArchiveEventsParams) (*ArchiveEventsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ArchiveEvents", p)
	ret0, _ := ret[0].(*ArchiveEventsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteEvents mocks base method.
func (m *MockEventServiceIface) DeleteEvents(p *DeleteEventsParams) (*DeleteEventsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteEvents", p)
	ret0, _ := ret[0].(*DeleteEventsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

// ListEventTypes mocks base method.
func (m *MockEventServiceIface) ListEventTypes(p *ListEventTypesParams) (*ListEventTypesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListEventTypes", p)
	ret0, _ := ret[0].(*ListEventTypesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListEvents mocks base method.
func (m *MockEventServiceIface) ListEvents(p *ListEventsParams) (*ListEventsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListEvents", p)
	ret0, _ := ret[0].(*ListEventsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

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

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

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

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

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

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

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