/*
* Copyright 2022-present Open Networking Foundation
* Licensed 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: /home/vinod/go/src/gerrit.opencord.org/voltha-go-controller/internal/pkg/intf/appif.go

// Package mock_intf is a generated GoMock package.
package mocks

import (
	context "context"
	reflect "reflect"
	intf "voltha-go-controller/internal/pkg/intf"

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

// MockApp is a mock of App interface.
type MockApp struct {
	ctrl     *gomock.Controller
	recorder *MockAppMockRecorder
}

// MockAppMockRecorder is the mock recorder for MockApp.
type MockAppMockRecorder struct {
	mock *MockApp
}

// NewMockApp creates a new mock instance.
func NewMockApp(ctrl *gomock.Controller) *MockApp {
	mock := &MockApp{ctrl: ctrl}
	mock.recorder = &MockAppMockRecorder{mock}
	return mock
}

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

// AddDevice mocks base method.
func (m *MockApp) AddDevice(arg0 context.Context, arg1, arg2, arg3 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "AddDevice", arg0, arg1, arg2, arg3)
}

// AddDevice indicates an expected call of AddDevice.
func (mr *MockAppMockRecorder) AddDevice(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDevice", reflect.TypeOf((*MockApp)(nil).AddDevice), arg0, arg1, arg2, arg3)
}

// DelDevice mocks base method.
func (m *MockApp) DelDevice(arg0 context.Context, arg1 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "DelDevice", arg0, arg1)
}

// DelDevice indicates an expected call of DelDevice.
func (mr *MockAppMockRecorder) DelDevice(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelDevice", reflect.TypeOf((*MockApp)(nil).DelDevice), arg0, arg1)
}

// DeviceDisableInd mocks base method.
func (m *MockApp) DeviceDisableInd(arg0 context.Context, arg1 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "DeviceDisableInd", arg0, arg1)
}

// DeviceDisableInd indicates an expected call of DeviceDisableInd.
func (mr *MockAppMockRecorder) DeviceDisableInd(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceDisableInd", reflect.TypeOf((*MockApp)(nil).DeviceDisableInd), arg0, arg1)
}

// DeviceDownInd mocks base method.
func (m *MockApp) DeviceDownInd(arg0 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "DeviceDownInd", arg0)
}

// DeviceDownInd indicates an expected call of DeviceDownInd.
func (mr *MockAppMockRecorder) DeviceDownInd(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceDownInd", reflect.TypeOf((*MockApp)(nil).DeviceDownInd), arg0)
}

// DeviceRebootInd mocks base method.
func (m *MockApp) DeviceRebootInd(arg0 context.Context, arg1, arg2, arg3 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "DeviceRebootInd", arg0, arg1, arg2, arg3)
}

// DeviceRebootInd indicates an expected call of DeviceRebootInd.
func (mr *MockAppMockRecorder) DeviceRebootInd(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceRebootInd", reflect.TypeOf((*MockApp)(nil).DeviceRebootInd), arg0, arg1, arg2, arg3)
}

// DeviceUpInd mocks base method.
func (m *MockApp) DeviceUpInd(arg0 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "DeviceUpInd", arg0)
}

// DeviceUpInd indicates an expected call of DeviceUpInd.
func (mr *MockAppMockRecorder) DeviceUpInd(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceUpInd", reflect.TypeOf((*MockApp)(nil).DeviceUpInd), arg0)
}

// PacketInInd mocks base method.
func (m *MockApp) PacketInInd(arg0 context.Context, arg1, arg2 string, arg3 []byte) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "PacketInInd", arg0, arg1, arg2, arg3)
}

// PacketInInd indicates an expected call of PacketInInd.
func (mr *MockAppMockRecorder) PacketInInd(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PacketInInd", reflect.TypeOf((*MockApp)(nil).PacketInInd), arg0, arg1, arg2, arg3)
}

// PortAddInd mocks base method.
func (m *MockApp) PortAddInd(arg0 context.Context, arg1 string, arg2 uint32, arg3 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "PortAddInd", arg0, arg1, arg2, arg3)
}

// PortAddInd indicates an expected call of PortAddInd.
func (mr *MockAppMockRecorder) PortAddInd(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortAddInd", reflect.TypeOf((*MockApp)(nil).PortAddInd), arg0, arg1, arg2, arg3)
}

// PortDelInd mocks base method.
func (m *MockApp) PortDelInd(arg0 context.Context, arg1, arg2 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "PortDelInd", arg0, arg1, arg2)
}

// PortDelInd indicates an expected call of PortDelInd.
func (mr *MockAppMockRecorder) PortDelInd(arg0, arg1, arg2 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortDelInd", reflect.TypeOf((*MockApp)(nil).PortDelInd), arg0, arg1, arg2)
}

// PortDownInd mocks base method.
func (m *MockApp) PortDownInd(arg0 context.Context, arg1, arg2 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "PortDownInd", arg0, arg1, arg2)
}

// PortDownInd indicates an expected call of PortDownInd.
func (mr *MockAppMockRecorder) PortDownInd(arg0, arg1, arg2 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortDownInd", reflect.TypeOf((*MockApp)(nil).PortDownInd), arg0, arg1, arg2)
}

// PortUpInd mocks base method.
func (m *MockApp) PortUpInd(arg0 context.Context, arg1, arg2 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "PortUpInd", arg0, arg1, arg2)
}

// PortUpInd indicates an expected call of PortUpInd.
func (mr *MockAppMockRecorder) PortUpInd(arg0, arg1, arg2 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortUpInd", reflect.TypeOf((*MockApp)(nil).PortUpInd), arg0, arg1, arg2)
}

// PortUpdateInd mocks base method.
func (m *MockApp) PortUpdateInd(arg0, arg1 string, arg2 uint32) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "PortUpdateInd", arg0, arg1, arg2)
}

// PortUpdateInd indicates an expected call of PortUpdateInd.
func (mr *MockAppMockRecorder) PortUpdateInd(arg0, arg1, arg2 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortUpdateInd", reflect.TypeOf((*MockApp)(nil).PortUpdateInd), arg0, arg1, arg2)
}

// ProcessFlowModResultIndication mocks base method.
func (m *MockApp) ProcessFlowModResultIndication(arg0 context.Context, arg1 intf.FlowStatus) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "ProcessFlowModResultIndication", arg0, arg1)
}

// ProcessFlowModResultIndication indicates an expected call of ProcessFlowModResultIndication.
func (mr *MockAppMockRecorder) ProcessFlowModResultIndication(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProcessFlowModResultIndication", reflect.TypeOf((*MockApp)(nil).ProcessFlowModResultIndication), arg0, arg1)
}

// IsFlowDelThresholdReached mocks base method.
func (m *MockApp) IsFlowDelThresholdReached(arg0 context.Context, arg1 string, arg2 string) bool {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "IsFlowDelThresholdReached", arg0, arg1, arg2)
	return false
}

// IsFlowDelThresholdReached indicates an expected call of IsFlowDelThresholdReached.
func (mr *MockAppMockRecorder) IsFlowDelThresholdReached(arg0, arg1, arg2 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsFlowDelThresholdReached", reflect.TypeOf((*MockApp)(nil).IsFlowDelThresholdReached), arg0, arg1, arg2)
}

// SetRebootFlag mocks base method.
func (m *MockApp) SetRebootFlag(arg0 bool) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "SetRebootFlag", arg0)
}

// SetRebootFlag indicates an expected call of SetRebootFlag.
func (mr *MockAppMockRecorder) SetRebootFlag(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetRebootFlag", reflect.TypeOf((*MockApp)(nil).SetRebootFlag), arg0)
}

// TriggerPendingMigrateServicesReq mocks base method.
func (m *MockApp) TriggerPendingMigrateServicesReq(arg0 context.Context, arg1 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "TriggerPendingMigrateServicesReq", arg0, arg1)
}

// TriggerPendingMigrateServicesReq indicates an expected call of TriggerPendingMigrateServicesReq.
func (mr *MockAppMockRecorder) TriggerPendingMigrateServicesReq(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TriggerPendingMigrateServicesReq", reflect.TypeOf((*MockApp)(nil).TriggerPendingMigrateServicesReq), arg0, arg1)
}

// TriggerPendingProfileDeleteReq mocks base method.
func (m *MockApp) TriggerPendingProfileDeleteReq(arg0 context.Context, arg1 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "TriggerPendingProfileDeleteReq", arg0, arg1)
}

// TriggerPendingProfileDeleteReq indicates an expected call of TriggerPendingProfileDeleteReq.
func (mr *MockAppMockRecorder) TriggerPendingProfileDeleteReq(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TriggerPendingProfileDeleteReq", reflect.TypeOf((*MockApp)(nil).TriggerPendingProfileDeleteReq), arg0, arg1)
}

// UpdateMvlanProfilesForDevice mocks base method.
func (m *MockApp) UpdateMvlanProfilesForDevice(arg0 context.Context, arg1 string) {
	m.ctrl.T.Helper()
	m.ctrl.Call(m, "UpdateMvlanProfilesForDevice", arg0, arg1)
}

// UpdateMvlanProfilesForDevice indicates an expected call of UpdateMvlanProfilesForDevice.
func (mr *MockAppMockRecorder) UpdateMvlanProfilesForDevice(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMvlanProfilesForDevice", reflect.TypeOf((*MockApp)(nil).UpdateMvlanProfilesForDevice), arg0, arg1)
}
