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

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

import (
	reflect "reflect"

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

// MockUsageServiceIface is a mock of UsageServiceIface interface.
type MockUsageServiceIface struct {
	ctrl     *gomock.Controller
	recorder *MockUsageServiceIfaceMockRecorder
	isgomock struct{}
}

// MockUsageServiceIfaceMockRecorder is the mock recorder for MockUsageServiceIface.
type MockUsageServiceIfaceMockRecorder struct {
	mock *MockUsageServiceIface
}

// NewMockUsageServiceIface creates a new mock instance.
func NewMockUsageServiceIface(ctrl *gomock.Controller) *MockUsageServiceIface {
	mock := &MockUsageServiceIface{ctrl: ctrl}
	mock.recorder = &MockUsageServiceIfaceMockRecorder{mock}
	return mock
}

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

// AddTrafficMonitor mocks base method.
func (m *MockUsageServiceIface) AddTrafficMonitor(p *AddTrafficMonitorParams) (*AddTrafficMonitorResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddTrafficMonitor", p)
	ret0, _ := ret[0].(*AddTrafficMonitorResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// AddTrafficType mocks base method.
func (m *MockUsageServiceIface) AddTrafficType(p *AddTrafficTypeParams) (*AddTrafficTypeResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "AddTrafficType", p)
	ret0, _ := ret[0].(*AddTrafficTypeResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteTrafficMonitor mocks base method.
func (m *MockUsageServiceIface) DeleteTrafficMonitor(p *DeleteTrafficMonitorParams) (*DeleteTrafficMonitorResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteTrafficMonitor", p)
	ret0, _ := ret[0].(*DeleteTrafficMonitorResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// DeleteTrafficType mocks base method.
func (m *MockUsageServiceIface) DeleteTrafficType(p *DeleteTrafficTypeParams) (*DeleteTrafficTypeResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteTrafficType", p)
	ret0, _ := ret[0].(*DeleteTrafficTypeResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// GenerateUsageRecords mocks base method.
func (m *MockUsageServiceIface) GenerateUsageRecords(p *GenerateUsageRecordsParams) (*GenerateUsageRecordsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GenerateUsageRecords", p)
	ret0, _ := ret[0].(*GenerateUsageRecordsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

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

// GetTrafficTypeID indicates an expected call of GetTrafficTypeID.
func (mr *MockUsageServiceIfaceMockRecorder) GetTrafficTypeID(keyword, physicalnetworkid any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{keyword, physicalnetworkid}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTrafficTypeID", reflect.TypeOf((*MockUsageServiceIface)(nil).GetTrafficTypeID), varargs...)
}

// ListTrafficMonitors mocks base method.
func (m *MockUsageServiceIface) ListTrafficMonitors(p *ListTrafficMonitorsParams) (*ListTrafficMonitorsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListTrafficMonitors", p)
	ret0, _ := ret[0].(*ListTrafficMonitorsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListTrafficTypeImplementors mocks base method.
func (m *MockUsageServiceIface) ListTrafficTypeImplementors(p *ListTrafficTypeImplementorsParams) (*ListTrafficTypeImplementorsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListTrafficTypeImplementors", p)
	ret0, _ := ret[0].(*ListTrafficTypeImplementorsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListTrafficTypes mocks base method.
func (m *MockUsageServiceIface) ListTrafficTypes(p *ListTrafficTypesParams) (*ListTrafficTypesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListTrafficTypes", p)
	ret0, _ := ret[0].(*ListTrafficTypesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListUsageRecords mocks base method.
func (m *MockUsageServiceIface) ListUsageRecords(p *ListUsageRecordsParams) (*ListUsageRecordsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListUsageRecords", p)
	ret0, _ := ret[0].(*ListUsageRecordsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListUsageServerMetrics mocks base method.
func (m *MockUsageServiceIface) ListUsageServerMetrics(p *ListUsageServerMetricsParams) (*ListUsageServerMetricsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListUsageServerMetrics", p)
	ret0, _ := ret[0].(*ListUsageServerMetricsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// ListUsageTypes mocks base method.
func (m *MockUsageServiceIface) ListUsageTypes(p *ListUsageTypesParams) (*ListUsageTypesResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListUsageTypes", p)
	ret0, _ := ret[0].(*ListUsageTypesResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// NewAddTrafficMonitorParams mocks base method.
func (m *MockUsageServiceIface) NewAddTrafficMonitorParams(url, zoneid string) *AddTrafficMonitorParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddTrafficMonitorParams", url, zoneid)
	ret0, _ := ret[0].(*AddTrafficMonitorParams)
	return ret0
}

// NewAddTrafficMonitorParams indicates an expected call of NewAddTrafficMonitorParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewAddTrafficMonitorParams(url, zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddTrafficMonitorParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewAddTrafficMonitorParams), url, zoneid)
}

// NewAddTrafficTypeParams mocks base method.
func (m *MockUsageServiceIface) NewAddTrafficTypeParams(physicalnetworkid, traffictype string) *AddTrafficTypeParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewAddTrafficTypeParams", physicalnetworkid, traffictype)
	ret0, _ := ret[0].(*AddTrafficTypeParams)
	return ret0
}

// NewAddTrafficTypeParams indicates an expected call of NewAddTrafficTypeParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewAddTrafficTypeParams(physicalnetworkid, traffictype any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddTrafficTypeParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewAddTrafficTypeParams), physicalnetworkid, traffictype)
}

// NewDeleteTrafficMonitorParams mocks base method.
func (m *MockUsageServiceIface) NewDeleteTrafficMonitorParams(id string) *DeleteTrafficMonitorParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteTrafficMonitorParams", id)
	ret0, _ := ret[0].(*DeleteTrafficMonitorParams)
	return ret0
}

// NewDeleteTrafficMonitorParams indicates an expected call of NewDeleteTrafficMonitorParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewDeleteTrafficMonitorParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteTrafficMonitorParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewDeleteTrafficMonitorParams), id)
}

// NewDeleteTrafficTypeParams mocks base method.
func (m *MockUsageServiceIface) NewDeleteTrafficTypeParams(id string) *DeleteTrafficTypeParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewDeleteTrafficTypeParams", id)
	ret0, _ := ret[0].(*DeleteTrafficTypeParams)
	return ret0
}

// NewDeleteTrafficTypeParams indicates an expected call of NewDeleteTrafficTypeParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewDeleteTrafficTypeParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewDeleteTrafficTypeParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewDeleteTrafficTypeParams), id)
}

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

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

// NewListTrafficMonitorsParams mocks base method.
func (m *MockUsageServiceIface) NewListTrafficMonitorsParams(zoneid string) *ListTrafficMonitorsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListTrafficMonitorsParams", zoneid)
	ret0, _ := ret[0].(*ListTrafficMonitorsParams)
	return ret0
}

// NewListTrafficMonitorsParams indicates an expected call of NewListTrafficMonitorsParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewListTrafficMonitorsParams(zoneid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListTrafficMonitorsParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewListTrafficMonitorsParams), zoneid)
}

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

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

// NewListTrafficTypesParams mocks base method.
func (m *MockUsageServiceIface) NewListTrafficTypesParams(physicalnetworkid string) *ListTrafficTypesParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListTrafficTypesParams", physicalnetworkid)
	ret0, _ := ret[0].(*ListTrafficTypesParams)
	return ret0
}

// NewListTrafficTypesParams indicates an expected call of NewListTrafficTypesParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewListTrafficTypesParams(physicalnetworkid any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListTrafficTypesParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewListTrafficTypesParams), physicalnetworkid)
}

// NewListUsageRecordsParams mocks base method.
func (m *MockUsageServiceIface) NewListUsageRecordsParams(enddate, startdate string) *ListUsageRecordsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewListUsageRecordsParams", enddate, startdate)
	ret0, _ := ret[0].(*ListUsageRecordsParams)
	return ret0
}

// NewListUsageRecordsParams indicates an expected call of NewListUsageRecordsParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewListUsageRecordsParams(enddate, startdate any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListUsageRecordsParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewListUsageRecordsParams), enddate, startdate)
}

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

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

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

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

// NewRemoveRawUsageRecordsParams mocks base method.
func (m *MockUsageServiceIface) NewRemoveRawUsageRecordsParams(interval int) *RemoveRawUsageRecordsParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewRemoveRawUsageRecordsParams", interval)
	ret0, _ := ret[0].(*RemoveRawUsageRecordsParams)
	return ret0
}

// NewRemoveRawUsageRecordsParams indicates an expected call of NewRemoveRawUsageRecordsParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewRemoveRawUsageRecordsParams(interval any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRemoveRawUsageRecordsParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewRemoveRawUsageRecordsParams), interval)
}

// NewUpdateTrafficTypeParams mocks base method.
func (m *MockUsageServiceIface) NewUpdateTrafficTypeParams(id string) *UpdateTrafficTypeParams {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NewUpdateTrafficTypeParams", id)
	ret0, _ := ret[0].(*UpdateTrafficTypeParams)
	return ret0
}

// NewUpdateTrafficTypeParams indicates an expected call of NewUpdateTrafficTypeParams.
func (mr *MockUsageServiceIfaceMockRecorder) NewUpdateTrafficTypeParams(id any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewUpdateTrafficTypeParams", reflect.TypeOf((*MockUsageServiceIface)(nil).NewUpdateTrafficTypeParams), id)
}

// RemoveRawUsageRecords mocks base method.
func (m *MockUsageServiceIface) RemoveRawUsageRecords(p *RemoveRawUsageRecordsParams) (*RemoveRawUsageRecordsResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RemoveRawUsageRecords", p)
	ret0, _ := ret[0].(*RemoveRawUsageRecordsResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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

// UpdateTrafficType mocks base method.
func (m *MockUsageServiceIface) UpdateTrafficType(p *UpdateTrafficTypeParams) (*UpdateTrafficTypeResponse, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateTrafficType", p)
	ret0, _ := ret[0].(*UpdateTrafficTypeResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

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