/*
 * Copyright 2018-2022 Open Networking Foundation (ONF) and the ONF Contributors

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

//Package mocks provides the mocks for openolt-adapter.
package mocks

import (
	"context"
	"errors"

	"github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
	"github.com/opencord/voltha-protos/v5/go/voltha"
)

// MockEventProxy for mocking EventProxyIntf
type MockEventProxy struct {
}

// SendDeviceEvent mocks the SendDeviceEvent function
func (me *MockEventProxy) SendDeviceEvent(ctx context.Context, deviceEvent *voltha.DeviceEvent, category voltha.EventCategory_Types,
	subCategory voltha.EventSubCategory_Types, raisedTs int64) error {
	if raisedTs == 0 {
		return errors.New("raisedTS cannot be zero")
	}
	return nil
}

// SendKpiEvent mocks the SendKpiEvent function
func (me *MockEventProxy) SendKpiEvent(ctx context.Context, id string, deviceEvent *voltha.KpiEvent2, category voltha.EventCategory_Types,
	subCategory voltha.EventSubCategory_Types, raisedTs int64) error {
	if raisedTs == 0 {
		return errors.New("raisedTS cannot be zero")
	}
	return nil
}

// SendRPCEvent mocks the SendRPCEvent function
func (me *MockEventProxy) SendRPCEvent(ctx context.Context, id string, deviceEvent *voltha.RPCEvent, category voltha.EventCategory_Types,
	subCategory *voltha.EventSubCategory_Types, raisedTs int64) error {
	if raisedTs == 0 {
		return errors.New("raisedTS cannot be zero")
	}
	return nil
}

// EnableLivenessChannel mocks the EnableLivenessChannel function
func (me *MockEventProxy) EnableLivenessChannel(ctx context.Context, enable bool) chan bool {
	return nil
}

// SendLiveness mocks the SendLiveness function
func (me *MockEventProxy) SendLiveness(ctx context.Context) error {
	return nil
}

// Start starts the proxy
func (me *MockEventProxy) Start() error {
	return nil
}

// Stop stops the proxy
func (me *MockEventProxy) Stop() {
}

//SendDeviceEventWithKey mocks SendDeviceEventWithKey
func (me *MockEventProxy) SendDeviceEventWithKey(ctx context.Context, deviceEvent *voltha.DeviceEvent, category eventif.EventCategory,
	subCategory eventif.EventSubCategory, raisedTs int64, key string) error {
	return nil
}
