//package voltha
package main

/*
#include <stdlib.h>
#include "voltha-defs.h"
 */
import "C"

import (
	"log"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/hashicorp/consul/api"
	pb "github.com/opencord/voltha/netconf/translator/voltha"
	pb_health "github.com/opencord/voltha/netconf/translator/voltha/health"
	pb_device "github.com/opencord/voltha/netconf/translator/voltha/device"
	pb_adapter "github.com/opencord/voltha/netconf/translator/voltha/adapter"
	pb_logical_device "github.com/opencord/voltha/netconf/translator/voltha/logical_device"
	pb_openflow "github.com/opencord/voltha/netconf/translator/voltha/openflow_13"
	pb_any "github.com/golang/protobuf/ptypes/any"
	"unsafe"
	"fmt"
)

const (
	default_consul_address = "10.100.198.220:8500"
	default_grpc_address   = "localhost:50555"
	grpc_service_name      = "voltha-grpc"
)

var (
	GrpcConn           *grpc.ClientConn              = nil
	VolthaGlobalClient pb.VolthaGlobalServiceClient  = nil
	HealthClient       pb_health.HealthServiceClient = nil
	ConsulClient       *api.Client                   = nil
	GrpcServiceAddress string                        = "localhost:50555"
)

func init() {
	ConsulClient = connect_to_consul(default_consul_address)
	GrpcServiceAddress = get_consul_service_address(grpc_service_name)
	GrpcConn = connect_to_grpc(GrpcServiceAddress)

	VolthaGlobalClient = pb.NewVolthaGlobalServiceClient(GrpcConn)
	HealthClient = pb_health.NewHealthServiceClient(GrpcConn)
}

func connect_to_consul(consul_address string) *api.Client {
	cfg := api.Config{Address: consul_address }

	log.Printf("Connecting to consul - address: %s", consul_address)

	client, err := api.NewClient(&cfg)
	if err != nil {
		panic(err)
	}

	log.Printf("Connected to consul - address: %s", consul_address)

	return client
}

func get_consul_service_address(service_name string) string {
	var service []*api.CatalogService
	var err error

	log.Printf("Getting consul service - name:%s", service_name)

	if service, _, _ = ConsulClient.Catalog().Service(service_name, "", nil); err != nil {
		panic(err)
	}

	address := fmt.Sprintf("%s:%d", service[0].ServiceAddress, service[0].ServicePort)

	log.Printf("Got consul service - name:%s, address:%s", service_name, address)

	return address
}

func connect_to_grpc(grpc_address string) *grpc.ClientConn {
	var err error
	var client *grpc.ClientConn

	log.Printf("Connecting to grpc - address: %s", grpc_address)

	// Set up a connection to the server.
	client, err = grpc.Dial(grpc_address, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %s", err.Error())
	}

	log.Printf("Connected to grpc - address: %s", grpc_address)

	return client
}
// Utility methods

// -------------------------------------------------
// C to Protobuf conversion methods
// -------------------------------------------------

func _c_to_proto_Address(address C.isDevice_Address) *pb_device.Device {
	var device *pb_device.Device

	// Identify the address type to assign
	switch address.Type {
	case C.MAC:
		device.Address = &pb_device.Device_MacAddress{
			MacAddress: C.GoString(address.Value),
		}
		break
	case C.IPV4:
		device.Address = &pb_device.Device_Ipv4Address{
			Ipv4Address: C.GoString(address.Value),
		}
		break
	case C.IPV6:
		device.Address = &pb_device.Device_Ipv6Address{
			Ipv6Address: C.GoString(address.Value),
		}
		break
	case C.HOST_AND_PORT:
		device.Address = &pb_device.Device_HostAndPort{
			HostAndPort: C.GoString(address.Value),
		}
		break
	}

	return device
}

// -------------------------------------------------
// Protobuf to C conversion methods
// -------------------------------------------------

func _proto_to_c_Adapters(instances []*pb_adapter.Adapter) C.AdapterArray {
	// TODO: not implemented
	var result C.AdapterArray
	return result
}
func _proto_to_c_LogicalDevices(instances []*pb_logical_device.LogicalDevice) C.LogicalDeviceArray {
	// TODO: not implemented
	var result C.LogicalDeviceArray
	return result
}
func _proto_to_c_DeviceTypes(instances []*pb_device.DeviceType) C.DeviceTypeArray {
	// TODO: not implemented
	var result C.DeviceTypeArray
	return result
}
func _proto_to_c_AlarmFilters(instances []*pb.AlarmFilter) C.AlarmFilterArray {
	// TODO: not implemented
	var result C.AlarmFilterArray
	return result
}
func _proto_to_c_DeviceGroups(instances []*pb.DeviceGroup) C.DeviceGroupArray {
	// TODO: not implemented
	var result C.DeviceGroupArray
	return result
}
func _proto_to_c_ProxyAddress(proxyAddress *pb_device.Device_ProxyAddress) *C.Device_ProxyAddress {
	// TODO: not implemented
	var result *C.Device_ProxyAddress
	defer C.free(unsafe.Pointer(result))
	return result
}
func _proto_to_c_Ports(ports []*pb_device.Port) C.PortArray {
	// TODO: not implemented
	var result C.PortArray
	return result
}
func _proto_to_c_Flows(flows *pb_openflow.Flows) *C.Flows {
	// TODO: not implemented
	var result *C.Flows
	defer C.free(unsafe.Pointer(result))
	return result
}
func _proto_to_c_FlowGroups(groups *pb_openflow.FlowGroups) *C.FlowGroups {
	// TODO: not implemented
	var result *C.FlowGroups
	defer C.free(unsafe.Pointer(result))
	return result
}
func _proto_to_c_PmConfigs(configs *pb_device.PmConfigs) *C.PmConfigs {
	// TODO: not implemented
	var result *C.PmConfigs
	defer C.free(unsafe.Pointer(result))
	return result
}
func _proto_to_c_Custom(configs *pb_any.Any) *C.Any {
	// TODO: not implemented
	var result *C.Any
	defer C.free(unsafe.Pointer(result))
	return result
}
func _proto_to_c_HealthStatus(health *pb_health.HealthStatus) C.HealthStatus {
	var result C.HealthStatus

	var c_string *C.char
	defer C.free(unsafe.Pointer(c_string))

	if c_string = C.CString(health.GetState().String()); c_string != nil {
		result.State = c_string
	}

	return result
}

func _proto_to_c_VolthaInstances(instances []*pb.VolthaInstance) C.VolthaInstanceArray {
	var result C.VolthaInstanceArray
	var c_string *C.char
	var c_voltha_instance C.VolthaInstance
	defer C.free(unsafe.Pointer(c_string))

	sizeof := unsafe.Sizeof(c_voltha_instance)
	count := len(instances)
	result.size = C.int(count)

	c_items := C.malloc(C.size_t(result.size) * C.size_t(sizeof))
	defer C.free(unsafe.Pointer(c_items))

	// Array to the allocated space
	c_array := (*[1<<30 - 1]C.VolthaInstance)(c_items)

	for index, value := range instances {
		if c_string = C.CString(value.GetInstanceId()); c_string != nil {
			c_voltha_instance.InstanceId = c_string
		}
		if c_string = C.CString(value.GetVersion()); c_string != nil {
			c_voltha_instance.Version = c_string
		}
		if c_string = C.CString(value.GetLogLevel().String()); c_string != nil {
			c_voltha_instance.LogLevel = c_string
		}
		c_voltha_instance.Health = _proto_to_c_HealthStatus(value.GetHealth())
		c_voltha_instance.Adapters = _proto_to_c_Adapters(value.GetAdapters())
		c_voltha_instance.LogicalDevices = _proto_to_c_LogicalDevices(value.GetLogicalDevices())
		c_voltha_instance.Devices = _proto_to_c_Devices(value.GetDevices())
		c_voltha_instance.DeviceTypes = _proto_to_c_DeviceTypes(value.GetDeviceTypes())
		c_voltha_instance.DeviceGroups = _proto_to_c_DeviceGroups(value.GetDeviceGroups())
		c_voltha_instance.AlarmFilters = _proto_to_c_AlarmFilters(value.GetAlarmFilters())

		c_array[index] = c_voltha_instance
	}

	result.items = (*C.VolthaInstance)(unsafe.Pointer(c_array))

	return result
}
func _proto_to_c_Devices(instances []*pb_device.Device) C.DeviceArray {
	var result C.DeviceArray
	var c_string *C.char
	var c_device_instance C.Device
	defer C.free(unsafe.Pointer(c_string))

	sizeof := unsafe.Sizeof(c_device_instance)
	count := len(instances)
	result.size = C.int(count)

	c_items := C.malloc(C.size_t(result.size) * C.size_t(sizeof))
	defer C.free(unsafe.Pointer(c_items))

	c_array := (*[1<<30 - 1]C.Device)(c_items)

	for index, value := range instances {
		c_array[index] = _proto_to_c_Device(value)
	}

	result.items = (*C.Device)(unsafe.Pointer(c_array))

	return result
}
func _proto_to_c_Voltha(voltha *pb.Voltha) C.Voltha {
	var result C.Voltha
	var c_string *C.char
	defer C.free(unsafe.Pointer(c_string))

	if c_string = C.CString(voltha.GetVersion()); c_string != nil {
		result.Version = c_string
	}
	if c_string = C.CString(voltha.GetLogLevel().String()); c_string != nil {
		result.LogLevel = c_string
	}

	result.Instances = _proto_to_c_VolthaInstances(voltha.GetInstances())
	result.Adapters = _proto_to_c_Adapters(voltha.GetAdapters())
	result.LogicalDevices = _proto_to_c_LogicalDevices(voltha.GetLogicalDevices())
	result.Devices = _proto_to_c_Devices(voltha.GetDevices())
	result.DeviceGroups = _proto_to_c_DeviceGroups(voltha.GetDeviceGroups())

	return result
}

func _proto_to_c_Address(device *pb_device.Device) C.isDevice_Address {
	var address C.isDevice_Address
	var c_string *C.char
	defer C.free(unsafe.Pointer(c_string))

	switch device.GetAddress().(type) {
	case *pb_device.Device_MacAddress:
		address.Type = C.MAC
		c_string = C.CString(device.GetMacAddress())
		address.Value = c_string
	case *pb_device.Device_Ipv4Address:
		address.Type = C.IPV4
		c_string = C.CString(device.GetIpv4Address())
		address.Value = c_string
	case *pb_device.Device_Ipv6Address:
		address.Type = C.IPV6
		c_string = C.CString(device.GetIpv6Address())
		address.Value = c_string
	case *pb_device.Device_HostAndPort:
		address.Type = C.HOST_AND_PORT
		c_string = C.CString(device.GetHostAndPort())
		address.Value = c_string
	}
	return address
}

func _proto_to_c_Device(device *pb_device.Device) C.Device {
	var result C.Device
	var c_string *C.char
	defer C.free(unsafe.Pointer(c_string))

	if c_string = C.CString(device.GetId()); c_string != nil {
		result.Id = c_string
	}
	if c_string = C.CString(device.GetType()); c_string != nil {
		result.Type = c_string
	}
	if device.GetRoot() {
		result.Root = C.int(1)
	} else {
		result.Root = C.int(0)
	}
	if c_string = C.CString(device.GetParentId()); c_string != nil {
		result.ParentId = c_string
	}

	result.ParentPortNo = C.uint32_t(device.GetParentPortNo())

	if c_string = C.CString(device.GetVendor()); c_string != nil {
		result.Vendor = c_string
	}
	if c_string = C.CString(device.GetModel()); c_string != nil {
		result.Model = c_string
	}
	if c_string = C.CString(device.GetHardwareVersion()); c_string != nil {
		result.HardwareVersion = c_string
	}
	if c_string = C.CString(device.GetFirmwareVersion()); c_string != nil {
		result.FirmwareVersion = c_string
	}
	if c_string = C.CString(device.GetSoftwareVersion()); c_string != nil {
		result.SoftwareVersion = c_string
	}
	if c_string = C.CString(device.GetSerialNumber()); c_string != nil {
		result.SerialNumber = c_string
	}
	if c_string = C.CString(device.GetAdapter()); c_string != nil {
		result.Adapter = c_string
	}

	result.Vlan = C.uint32_t(device.GetVlan())
	result.ProxyAddress = _proto_to_c_ProxyAddress(device.GetProxyAddress())

	if c_string = C.CString(device.GetAdminState().String()); c_string != nil {
		result.AdminState = c_string
	}
	if c_string = C.CString(device.GetOperStatus().String()); c_string != nil {
		result.OperStatus = c_string
	}
	if c_string = C.CString(device.GetReason()); c_string != nil {
		result.Reason = c_string
	}
	if c_string = C.CString(device.GetConnectStatus().String()); c_string != nil {
		result.ConnectStatus = c_string
	}

	result.Custom = _proto_to_c_Custom(device.GetCustom())
	result.Ports = _proto_to_c_Ports(device.GetPorts())
	result.Flows = _proto_to_c_Flows(device.GetFlows())
	result.FlowGroups = _proto_to_c_FlowGroups(device.GetFlowGroups())
	result.PmConfigs = _proto_to_c_PmConfigs(device.GetPmConfigs())
	result.Address = _proto_to_c_Address(device)

	return result
}

// ---------------------------------------------------------
// Exported methods accessible through the shared library
// ---------------------------------------------------------

//export GetHealthStatus
func GetHealthStatus() C.HealthStatus {
	var output *pb_health.HealthStatus
	var err error

	if output, err = HealthClient.GetHealthStatus(context.Background(), &empty.Empty{}); output == nil || err != nil {
		log.Fatalf("Failed to retrieve health status: %s", err.Error())
	}

	return _proto_to_c_HealthStatus(output)
}

//export GetVoltha
func GetVoltha() C.Voltha {
	var output *pb.Voltha
	var err error
	if output, err = VolthaGlobalClient.GetVoltha(context.Background(), &empty.Empty{}); output == nil || err != nil {
		log.Fatalf("Failed to retrieve voltha information: %s", err.Error())
	}

	return _proto_to_c_Voltha(output)
}

//export ListDevices
func ListDevices() C.DeviceArray {
	var output *pb_device.Devices
	var err error
	if output, err = VolthaGlobalClient.ListDevices(context.Background(), &empty.Empty{});
		output == nil || err != nil {
		log.Fatalf("Failed to retrieve voltha information: %s", err.Error())
	}

	return _proto_to_c_Devices(output.Items)
}

//export ListVolthaInstances
func ListVolthaInstances() *C.char {
	return nil
}

//export ListLogicalDevices
func ListLogicalDevices() *C.char {
	return nil
}

//export GetLogicalDevice
func GetLogicalDevice(input *C.char) *C.char {
	return nil
}

//export ListLogicalDevicePorts
func ListLogicalDevicePorts(input *C.char) *C.char {
	return nil
}

//export ListLogicalDeviceFlows
func ListLogicalDeviceFlows(input *C.char) *C.char {
	return nil
}

//export CreateDevice
func CreateDevice(input C.Device) C.Device {
	log.Printf("Incoming C Device - type:%v, address_type: %v, address_value:%s",
		C.GoString(input.Type),
		C.int(input.Address.Type),
		C.GoString(input.Address.Value),
	)

	device := _c_to_proto_Address(input.Address)
	device.Type = C.GoString(input.Type)

	var output *pb_device.Device
	var err error

	if output, err = VolthaGlobalClient.CreateDevice(context.Background(), device);
		output == nil || err != nil {
		log.Fatalf("Failed to create device: %s", err.Error())
	}

	return _proto_to_c_Device(output)
}

// Debugging code
func TestSerialize() {
	var object C.Device

	object.Type = C.CString("simulated_olt")
	object.Address.Type = 3
	object.Address.Value = C.CString("172.16.1.233:123")

	//xmlObject, _ := xml.Marshal(object)
	//
	//log.Printf("object: %+v", string(xmlObject))

	CreateDevice(object)
}

func main() {
	// We need the main function to make possible
	// CGO compiler to compile the package as C shared library
	//TestSerialize()
}
