/*
 * Copyright 2018-2024 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"
	"io"

	config "github.com/opencord/voltha-protos/v5/go/ext/config"
	"github.com/opencord/voltha-protos/v5/go/extension"
	openolt "github.com/opencord/voltha-protos/v5/go/openolt"
	tech_profile "github.com/opencord/voltha-protos/v5/go/tech_profile"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

// MockOpenoltClient mock struct for OpenoltClient.
type MockOpenoltClient struct {
	counter     int
	IsRestarted bool
}

// DisableOlt mocks the DisableOlt function of Openoltclient.
func (ooc *MockOpenoltClient) DisableOlt(ctx context.Context, in *openolt.Empty, opts ...grpc.CallOption) (*openolt.Empty, error) {
	// return &openolt.Empty{}, nil
	if ooc.counter == 0 {
		ooc.counter++
		return &openolt.Empty{}, nil
	}
	return nil, errors.New("disableOlt failed")
}

// ReenableOlt mocks the ReenableOlt function of Openoltclient.
func (ooc *MockOpenoltClient) ReenableOlt(ctx context.Context, in *openolt.Empty, opts ...grpc.CallOption) (*openolt.Empty, error) {
	if ooc.counter == 0 {
		ooc.counter++
		return &openolt.Empty{}, nil
	}
	return nil, errors.New("reenable olt failed")
}

// ActivateOnu mocks the ActivateOnu function of Openoltclient.
func (ooc *MockOpenoltClient) ActivateOnu(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.Empty, error) {
	if in == nil {
		return nil, errors.New("invalid onuId")
	}
	return &openolt.Empty{}, nil
}

// DeactivateOnu mocks the DeactivateOnu function of Openoltclient.
func (ooc *MockOpenoltClient) DeactivateOnu(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// DeleteOnu mocks the DeleteOnu function of Openoltclient.
func (ooc *MockOpenoltClient) DeleteOnu(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// OmciMsgOut mocks the OmciMsgOut function of Openoltclient.
func (ooc *MockOpenoltClient) OmciMsgOut(ctx context.Context, in *openolt.OmciMsg, opts ...grpc.CallOption) (*openolt.Empty, error) {
	if in == nil {
		return nil, errors.New("invalid Omci Msg")
	}
	return &openolt.Empty{}, nil
}

// OnuPacketOut mocks the OnuPacketOut function of Openoltclient.
func (ooc *MockOpenoltClient) OnuPacketOut(ctx context.Context, in *openolt.OnuPacket, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// UplinkPacketOut mocks the UplinkPacketOut function of Openoltclient.
func (ooc *MockOpenoltClient) UplinkPacketOut(ctx context.Context, in *openolt.UplinkPacket, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// FlowAdd mocks the FlowAdd function of Openoltclient.
func (ooc *MockOpenoltClient) FlowAdd(ctx context.Context, in *openolt.Flow, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// FlowRemove mocks the FlowRemove function of Openoltclient.
func (ooc *MockOpenoltClient) FlowRemove(ctx context.Context, in *openolt.Flow, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// HeartbeatCheck mocks the HeartbeatCheck function of Openoltclient.
func (ooc *MockOpenoltClient) HeartbeatCheck(ctx context.Context, in *openolt.Empty, opts ...grpc.CallOption) (*openolt.Heartbeat, error) {
	return nil, nil
}

// EnablePonIf mocks the EnablePonIf function of Openoltclient.
func (ooc *MockOpenoltClient) EnablePonIf(ctx context.Context, in *openolt.Interface, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// DisablePonIf mocks the DisablePonIf function of Openoltclient.
func (ooc *MockOpenoltClient) DisablePonIf(ctx context.Context, in *openolt.Interface, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// GetDeviceInfo mocks the GetDeviceInfo function of Openoltclient.
func (ooc *MockOpenoltClient) GetDeviceInfo(ctx context.Context, in *openolt.Empty, opts ...grpc.CallOption) (*openolt.DeviceInfo, error) {
	if ooc.counter == 0 {
		ooc.counter++
		deviceInfo := &openolt.DeviceInfo{Vendor: "Openolt", Model: "1.0", HardwareVersion: "1.0", FirmwareVersion: "1.0", DeviceId: "olt", DeviceSerialNumber: "olt"}
		return deviceInfo, nil
	}
	if ooc.counter == 1 {
		ooc.counter++
		deviceInfo := &openolt.DeviceInfo{Vendor: "Openolt", Model: "1.0", HardwareVersion: "1.0", FirmwareVersion: "1.0", DeviceId: "", DeviceSerialNumber: "olt"}
		return deviceInfo, nil
	}
	if ooc.counter == 2 {
		ooc.counter++
		return nil, nil
	}

	return nil, errors.New("device info not found")
}

// Reboot mocks the Reboot function of Openoltclient.
func (ooc *MockOpenoltClient) Reboot(ctx context.Context, in *openolt.Empty, opts ...grpc.CallOption) (*openolt.Empty, error) {
	if ooc.counter == 0 {
		ooc.counter++
		ooc.IsRestarted = true
		return &openolt.Empty{}, nil
	}
	return nil, errors.New("reboot failed")
}

// CollectStatistics mocks the CollectStatistics function of Openoltclient.
func (ooc *MockOpenoltClient) CollectStatistics(ctx context.Context, in *openolt.Empty, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// CreateTrafficSchedulers mocks the CreateTrafficSchedulers function of Openoltclient.
func (ooc *MockOpenoltClient) CreateTrafficSchedulers(ctx context.Context, in *tech_profile.TrafficSchedulers, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// RemoveTrafficSchedulers mocks the RemoveTrafficSchedulers function of Openoltclient.
func (ooc *MockOpenoltClient) RemoveTrafficSchedulers(ctx context.Context, in *tech_profile.TrafficSchedulers, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// CreateTrafficQueues mocks the CreateTrafficQueues function of Openoltclient.
func (ooc *MockOpenoltClient) CreateTrafficQueues(ctx context.Context, in *tech_profile.TrafficQueues, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// RemoveTrafficQueues mocks the RemoveTrafficQueues function of Openoltclient.
func (ooc *MockOpenoltClient) RemoveTrafficQueues(ctx context.Context, in *tech_profile.TrafficQueues, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// DeleteGroup mocks the DeleteGroup RPC of Openoltclient.
func (ooc *MockOpenoltClient) DeleteGroup(ctx context.Context, in *openolt.Group, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// GetLogicalOnuDistance mocks the GetLogicalOnuDistance RPC of Openoltclient.
func (ooc *MockOpenoltClient) GetLogicalOnuDistance(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.OnuLogicalDistance, error) {
	return &openolt.OnuLogicalDistance{}, nil
}

// GetLogicalOnuDistanceZero mocks the GetLogicalOnuDistanceZero RPC of Openoltclient.
func (ooc *MockOpenoltClient) GetLogicalOnuDistanceZero(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.OnuLogicalDistance, error) {
	return &openolt.OnuLogicalDistance{}, nil
}

// EnableIndication mocks the EnableIndication function of Openoltclient.
func (ooc *MockOpenoltClient) EnableIndication(ctx context.Context, in *openolt.Empty, opts ...grpc.CallOption) (openolt.Openolt_EnableIndicationClient, error) {
	if ooc.counter < 2 {
		ooc.counter++
		mockInd := &mockOpenoltEnableIndicationClient{0}
		return mockInd, nil
	}
	if ooc.counter == 2 {
		ooc.counter++
		return nil, nil
	}
	return nil, errors.New("invalid method invocation")
}

type mockOpenoltEnableIndicationClient struct {
	count int
}

func (mock *mockOpenoltEnableIndicationClient) Recv() (*openolt.Indication, error) {
	if mock.count == 0 {
		mock.count++
		indi := &openolt.Indication{Data: &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: "Down"}}}
		return indi, nil
	}
	if mock.count == 1 {
		mock.count++
		return nil, errors.New("error, while processing indication")
	}

	return nil, io.EOF
}

func (mock *mockOpenoltEnableIndicationClient) Header() (metadata.MD, error) {
	return nil, nil
}

func (mock *mockOpenoltEnableIndicationClient) Trailer() metadata.MD {
	return nil
}

func (mock *mockOpenoltEnableIndicationClient) CloseSend() error {
	return nil
}

func (mock *mockOpenoltEnableIndicationClient) Context() context.Context {
	return context.Background()
}

func (mock *mockOpenoltEnableIndicationClient) SendMsg(m interface{}) error {
	return nil
}

func (mock *mockOpenoltEnableIndicationClient) RecvMsg(m interface{}) error {
	return nil
}

// GetExtValue mocks the GetExtValue function of Openoltclient.
func (ooc *MockOpenoltClient) GetExtValue(ctx context.Context, in *openolt.ValueParam, opts ...grpc.CallOption) (*extension.ReturnValues, error) {
	return &extension.ReturnValues{}, nil
}

// OnuItuPonAlarmSet mocks the OnuItuPonAlarmSet function of Openoltclient.
func (ooc *MockOpenoltClient) OnuItuPonAlarmSet(ctx context.Context, in *config.OnuItuPonAlarm, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// PerformGroupOperation mocks the PerformGroupOperation function of Openoltclient.
func (ooc *MockOpenoltClient) PerformGroupOperation(ctx context.Context, in *openolt.Group, opts ...grpc.CallOption) (*openolt.Empty, error) {
	return &openolt.Empty{}, nil
}

// GetOnuStatistics mocks the GetOnuStatistics function of Openoltclient.
func (ooc *MockOpenoltClient) GetOnuStatistics(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.OnuStatistics, error) {
	return &openolt.OnuStatistics{}, nil
}

// GetGemPortStatistics mocks the GetGemPortStatistics function of Openoltclient.
func (ooc *MockOpenoltClient) GetGemPortStatistics(ctx context.Context, in *openolt.OnuPacket, opts ...grpc.CallOption) (*openolt.GemPortStatistics, error) {
	return &openolt.GemPortStatistics{}, nil
}

// GetPonRxPower mocks the GetPonRxPower function of Openoltclient.
func (ooc *MockOpenoltClient) GetPonRxPower(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.PonRxPowerData, error) {
	return &openolt.PonRxPowerData{}, nil
}

// GetOnuInfo mocks the GetOnuInfo function of Openoltclient.
func (ooc *MockOpenoltClient) GetOnuInfo(ctx context.Context, in *openolt.Onu, opts ...grpc.CallOption) (*openolt.OnuInfo, error) {
	return &openolt.OnuInfo{}, nil
}

// GetPonInterfaceInfo mocks the GetPonInterfaceInfo function of Openoltclient.
func (ooc *MockOpenoltClient) GetPonInterfaceInfo(ctx context.Context, in *openolt.Interface, opts ...grpc.CallOption) (*openolt.PonIntfInfo, error) {
	return &openolt.PonIntfInfo{}, nil
}
