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

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

import (
	"context"
	"errors"
	"fmt"

	"github.com/opencord/voltha-go/kafka"
	"github.com/opencord/voltha-protos/go/voltha"
)

// MockCoreProxy mocks the CoreProxy interface
type MockCoreProxy struct {
	// Values to be used in test can reside inside this structure
	// TODO store relevant info in this, use this info for negative and positive tests
	Devices map[string]*voltha.Device
}

// UpdateCoreReference mock updatesCoreReference
func (mcp *MockCoreProxy) UpdateCoreReference(deviceID string, coreReference string) {
	panic("implement me")
}

// DeleteCoreReference mock DeleteCoreReference function
func (mcp *MockCoreProxy) DeleteCoreReference(deviceID string) {
	panic("implement me")
}

// GetCoreTopic implements mock GetCoreTopic
func (mcp *MockCoreProxy) GetCoreTopic(deviceID string) kafka.Topic {
	panic("implement me")
}

// GetAdapterTopic implements mock GetAdapterTopic
func (mcp *MockCoreProxy) GetAdapterTopic(args ...string) kafka.Topic {
	panic("implement me")
}

// RegisterAdapter implements mock RegisterAdapter
func (mcp *MockCoreProxy) RegisterAdapter(ctx context.Context, adapter *voltha.Adapter,
	deviceTypes *voltha.DeviceTypes) error {
	if ctx == nil || adapter == nil || deviceTypes == nil {
		return errors.New("registerAdapter func parameters cannot be nil")
	}
	return nil
}

// DeviceUpdate implements mock DeviceUpdate
func (mcp *MockCoreProxy) DeviceUpdate(ctx context.Context, device *voltha.Device) error {
	if device.Id == "" {
		return errors.New("no Device")
	}
	return nil
}

// PortCreated implements mock PortCreated
func (mcp *MockCoreProxy) PortCreated(ctx context.Context, deviceID string, port *voltha.Port) error {
	if deviceID == "" {
		return errors.New("no deviceID")
	}
	if port.Type > 7 {
		return errors.New("invalid porttype")
	}
	return nil
}

// PortsStateUpdate implements mock PortsStateUpdate
func (mcp *MockCoreProxy) PortsStateUpdate(ctx context.Context, deviceID string, operStatus voltha.OperStatus_OperStatus) error {
	if deviceID == "" {
		return errors.New("no Device")
	}
	return nil
}

// DeleteAllPorts implements mock DeleteAllPorts
func (mcp *MockCoreProxy) DeleteAllPorts(ctx context.Context, deviceID string) error {
	if deviceID == "" {
		return errors.New("no Device id")
	}
	return nil
}

// DeviceStateUpdate implements mock DeviceStateUpdate
func (mcp *MockCoreProxy) DeviceStateUpdate(ctx context.Context, deviceID string,
	connStatus voltha.ConnectStatus_ConnectStatus, operStatus voltha.OperStatus_OperStatus) error {
	if deviceID == "" {
		return errors.New("no Device id")
	}
	return nil
}

// ChildDeviceDetected implements mock ChildDeviceDetected
func (mcp *MockCoreProxy) ChildDeviceDetected(ctx context.Context, parentdeviceID string, parentPortNo int,
	childDeviceType string, channelID int, vendorID string, serialNumber string, onuID int64) (*voltha.Device, error) {
	if parentdeviceID == "" {
		return nil, errors.New("no deviceID")
	}
	return nil, nil
}

// ChildDevicesLost implements mock ChildDevicesLost.
func (mcp *MockCoreProxy) ChildDevicesLost(ctx context.Context, parentdeviceID string) error {
	//panic("implement me")
	if parentdeviceID == "" {
		return errors.New("no device id")
	}
	return nil
}

// ChildDevicesDetected implements mock ChildDevicesDetecte
func (mcp *MockCoreProxy) ChildDevicesDetected(ctx context.Context, parentdeviceID string) error {
	if parentdeviceID == "" {
		return errors.New("no device id")
	}
	return nil
}

// GetDevice implements mock GetDevice
func (mcp *MockCoreProxy) GetDevice(ctx context.Context, parentdeviceID string, deviceID string) (*voltha.Device, error) {
	if parentdeviceID == "" || deviceID == "" {
		return &voltha.Device{}, errors.New("no deviceID")
	}
	for k, v := range mcp.Devices {
		if k == "olt" {
			return v, nil
		}
	}
	return nil, errors.New("device detection failed")
}

// GetChildDevice implements mock GetChildDevice
func (mcp *MockCoreProxy) GetChildDevice(ctx context.Context, parentdeviceID string, kwargs map[string]interface{}) (*voltha.Device, error) {

	if parentdeviceID == "" {
		return nil, errors.New("device detection failed")
	}
	onuID := kwargs["onu_id"]
	var onuDevice *voltha.Device
	for _, val := range mcp.Devices {
		if val.GetId() == fmt.Sprintf("%v", onuID) {
			onuDevice = val
			break
		}
	}
	if onuDevice != nil {
		return onuDevice, nil
	}
	//return &voltha.Device{}, nil
	return nil, errors.New("device detection failed")
}

// GetChildDevices implements mock GetChildDevices
func (mcp *MockCoreProxy) GetChildDevices(ctx context.Context, parentdeviceID string) (*voltha.Devices, error) {
	if parentdeviceID == "" {
		return nil, errors.New("no deviceID")
	}
	onuDevices := make([]*voltha.Device, 0)

	for _, val := range mcp.Devices {
		if val != nil {
			onuDevices = append(onuDevices, val)
		}
	}

	deviceList := &voltha.Devices{Items: onuDevices}
	if len(deviceList.Items) > 0 {
		return deviceList, nil
	}
	return nil, errors.New("device detection failed")
}

// SendPacketIn  implements mock SendPacketIn
func (mcp *MockCoreProxy) SendPacketIn(ctx context.Context, deviceID string, port uint32, pktPayload []byte) error {
	if deviceID == "" {
		return errors.New("no Device ID")
	}
	return nil
}
