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

	"github.com/opencord/voltha-lib-go/v7/pkg/db"
	tp_pb "github.com/opencord/voltha-protos/v5/go/tech_profile"
)

// MockTechProfile mock struct for OpenoltClient.
type MockTechProfile struct {
	TpID uint32
}

// SetKVClient to mock techprofile SetKVClient method
func (m MockTechProfile) SetKVClient(ctx context.Context, pathPrefix string) *db.Backend {
	return &db.Backend{Client: &MockKVClient{}}
}

// CloseKVClient to mock techprofile CloseKVClient method
func (m MockTechProfile) CloseKVClient(ctx context.Context) {
}

// GetTPInstance to mock techprofile GetTPInstance method
func (m MockTechProfile) GetTPInstance(ctx context.Context, path string) (interface{}, error) {
	logger.Debug(ctx, "GetTPInstanceFromKVStore")
	var usGemPortAttributeList []*tp_pb.GemPortAttributes
	var dsGemPortAttributeList []*tp_pb.GemPortAttributes
	usGemPortAttributeList = append(usGemPortAttributeList, &tp_pb.GemPortAttributes{
		GemportId: 1,
		PbitMap:   "0b11111111",
	})
	dsGemPortAttributeList = append(dsGemPortAttributeList, &tp_pb.GemPortAttributes{
		GemportId: 1,
		PbitMap:   "0b11111111",
	})
	return &tp_pb.TechProfileInstance{
		Name:                 "mock-tech-profile",
		SubscriberIdentifier: "257",
		ProfileType:          "mock",
		Version:              0,
		NumGemPorts:          1,
		InstanceControl: &tp_pb.InstanceControl{
			Onu:               "multi-instance",
			Uni:               "single-instance",
			MaxGemPayloadSize: "",
		},
		UsScheduler: &tp_pb.SchedulerAttributes{
			AllocId:      1,
			Direction:    tp_pb.Direction_UPSTREAM,
			AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_None,
			Priority:     0,
			Weight:       0,
			QSchedPolicy: tp_pb.SchedulingPolicy_WRR,
		},
		DsScheduler: &tp_pb.SchedulerAttributes{
			AllocId:      1,
			Direction:    tp_pb.Direction_DOWNSTREAM,
			AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_None,
			Priority:     0,
			Weight:       0,
			QSchedPolicy: tp_pb.SchedulingPolicy_WRR,
		},
		UpstreamGemPortAttributeList:   usGemPortAttributeList,
		DownstreamGemPortAttributeList: dsGemPortAttributeList,
	}, nil

}

// CreateTechProfileInstance to mock techprofile CreateTechProfileInstance method
func (m MockTechProfile) CreateTechProfileInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfID uint32) (interface{}, error) {

	var usGemPortAttributeList []*tp_pb.GemPortAttributes
	var dsGemPortAttributeList []*tp_pb.GemPortAttributes
	if techProfiletblID == 64 {
		usGemPortAttributeList = append(usGemPortAttributeList, &tp_pb.GemPortAttributes{
			GemportId: 1,
			PbitMap:   "0b11111111",
		})
		dsGemPortAttributeList = append(dsGemPortAttributeList, &tp_pb.GemPortAttributes{
			GemportId: 1,
			PbitMap:   "0b11111111",
		})
		return &tp_pb.TechProfileInstance{
			Name:                 "mock-tech-profile",
			SubscriberIdentifier: "257",
			ProfileType:          "mock",
			Version:              0,
			NumGemPorts:          1,
			InstanceControl: &tp_pb.InstanceControl{
				Onu:               "multi-instance",
				Uni:               "single-instance",
				MaxGemPayloadSize: "",
			},
			UsScheduler: &tp_pb.SchedulerAttributes{
				AllocId:      1,
				Direction:    tp_pb.Direction_UPSTREAM,
				AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_None,
				Priority:     0,
				Weight:       0,
				QSchedPolicy: tp_pb.SchedulingPolicy_WRR,
			},
			DsScheduler: &tp_pb.SchedulerAttributes{
				AllocId:      1,
				Direction:    tp_pb.Direction_DOWNSTREAM,
				AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_None,
				Priority:     0,
				Weight:       0,
				QSchedPolicy: tp_pb.SchedulingPolicy_WRR,
			},
			UpstreamGemPortAttributeList:   usGemPortAttributeList,
			DownstreamGemPortAttributeList: dsGemPortAttributeList,
		}, nil
	} else if techProfiletblID == 65 {
		return &tp_pb.EponTechProfileInstance{
			Name:                         "mock-epon-profile",
			SubscriberIdentifier:         "257",
			ProfileType:                  "mock",
			Version:                      0,
			NumGemPorts:                  2,
			UpstreamQueueAttributeList:   nil,
			DownstreamQueueAttributeList: nil,
		}, nil
	} else {
		return nil, nil
	}
}

// DeleteTechProfileInstance to mock techprofile DeleteTechProfileInstance method
func (m MockTechProfile) DeleteTechProfileInstance(ctx context.Context, techProfiletblID uint32, uniPortName string) error {
	return nil
}

// GetprotoBufParamValue to mock techprofile GetprotoBufParamValue method
func (m MockTechProfile) GetprotoBufParamValue(ctx context.Context, paramType string, paramKey string) int32 {
	return 0

}

// GetUsScheduler to mock techprofile GetUsScheduler method
func (m MockTechProfile) GetUsScheduler(tpInstance *tp_pb.TechProfileInstance) *tp_pb.SchedulerConfig {
	return &tp_pb.SchedulerConfig{}

}

// GetDsScheduler to mock techprofile GetDsScheduler method
func (m MockTechProfile) GetDsScheduler(tpInstance *tp_pb.TechProfileInstance) *tp_pb.SchedulerConfig {
	return &tp_pb.SchedulerConfig{}
}

// GetTrafficScheduler to mock techprofile GetTrafficScheduler method
func (m MockTechProfile) GetTrafficScheduler(tpInstance *tp_pb.TechProfileInstance, SchedCfg *tp_pb.SchedulerConfig,
	ShapingCfg *tp_pb.TrafficShapingInfo) *tp_pb.TrafficScheduler {
	return &tp_pb.TrafficScheduler{}

}

// GetTrafficQueues to mock techprofile GetTrafficQueues method
func (m MockTechProfile) GetTrafficQueues(ctx context.Context, tp *tp_pb.TechProfileInstance, Dir tp_pb.Direction) ([]*tp_pb.TrafficQueue, error) {
	return []*tp_pb.TrafficQueue{{}}, nil
}

// GetMulticastTrafficQueues to mock techprofile GetMulticastTrafficQueues method
func (m MockTechProfile) GetMulticastTrafficQueues(ctx context.Context, tp *tp_pb.TechProfileInstance) []*tp_pb.TrafficQueue {
	return []*tp_pb.TrafficQueue{{}}
}

// GetGemportForPbit to mock techprofile GetGemportForPbit method
func (m MockTechProfile) GetGemportForPbit(ctx context.Context, tpInst interface{}, Dir tp_pb.Direction, pbit uint32) interface{} {
	return &tp_pb.GemPortAttributes{
		GemportId:     1,
		PbitMap:       "0b11111111",
		AesEncryption: "false",
	}
}

// FindAllTpInstances to mock techprofile FindAllTpInstances method
func (m MockTechProfile) FindAllTpInstances(ctx context.Context, oltDeviceID string, tpID uint32, ponIntf uint32, onuID uint32) interface{} {
	return []tp_pb.TechProfileInstance{}
}

// GetResourceID to mock techprofile GetResourceID method
func (m MockTechProfile) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
	return []uint32{}, nil
}

// FreeResourceID to mock techprofile FreeResourceID method
func (m MockTechProfile) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
	return nil
}

// GetTechProfileInstanceKey to mock techprofile GetTechProfileInstanceKey method
func (m MockTechProfile) GetTechProfileInstanceKey(ctx context.Context, tpID uint32, uniPortName string) string {
	return ""
}
