/*
* Copyright 2022-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 sysrepo

//#cgo LDFLAGS: -lsysrepo -lyang -Wl,--allow-multiple-definition
//#include "plugin.c"
import "C"
import (
	"context"
	"fmt"
	"strconv"

	"github.com/opencord/voltha-lib-go/v7/pkg/log"
	"github.com/opencord/voltha-northbound-bbf-adapter/internal/core"
)

//export get_devices_cb
func get_devices_cb(session *C.sr_session_ctx_t, parent **C.lyd_node) C.sr_error_t {
	//This function is a callback for the retrieval of devices from sysrepo
	//The "export" comment instructs CGO to create a C function for it

	ctx := context.Background()
	logger.Debug(ctx, "processing-get-devices-request")

	if session == nil {
		logger.Error(ctx, "sysrepo-get-devices-null-session")
		return C.SR_ERR_OPERATION_FAILED
	}

	if parent == nil {
		logger.Error(ctx, "sysrepo-get-devices-null-parent-node")
		return C.SR_ERR_OPERATION_FAILED
	}

	if core.AdapterInstance == nil {
		logger.Error(ctx, "sysrepo-get-devices-nil-translator")
		return C.SR_ERR_OPERATION_FAILED
	}

	devices, err := core.AdapterInstance.GetDevices(ctx)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-devices-translator-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	err = updateYangTree(ctx, session, parent, devices)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-devices-update-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	logger.Info(ctx, "devices-information-request-served")

	return C.SR_ERR_OK
}

//export get_services_cb
func get_services_cb(session *C.sr_session_ctx_t, parent **C.lyd_node) C.sr_error_t {
	//This function is a callback for the retrieval of devices from sysrepo
	//The "export" comment instructs CGO to create a C function for it

	ctx := context.Background()
	logger.Debug(ctx, "processing-get-services-request")

	if session == nil {
		logger.Error(ctx, "sysrepo-get-services-null-session")
		return C.SR_ERR_OPERATION_FAILED
	}

	if parent == nil {
		logger.Error(ctx, "sysrepo-get-services-null-parent-node")
		return C.SR_ERR_OPERATION_FAILED
	}

	if core.AdapterInstance == nil {
		logger.Error(ctx, "sysrepo-get-services-nil-translator")
		return C.SR_ERR_OPERATION_FAILED
	}

	services, err := core.AdapterInstance.GetServices(ctx)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-services-translation-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	err = updateYangTree(ctx, session, parent, services)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-services-update-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	logger.Info(ctx, "services-information-request-served")

	return C.SR_ERR_OK
}

//export get_vlans_cb
func get_vlans_cb(session *C.sr_session_ctx_t, parent **C.lyd_node) C.sr_error_t {
	//This function is a callback for the retrieval of vlans from sysrepo
	//The "export" comment instructs CGO to create a C function for it

	ctx := context.Background()
	logger.Debug(ctx, "processing-get-vlans-request")

	if session == nil {
		logger.Error(ctx, "sysrepo-get-vlans-null-session")
		return C.SR_ERR_OPERATION_FAILED
	}

	if parent == nil {
		logger.Error(ctx, "sysrepo-get-vlans-null-parent-node")
		return C.SR_ERR_OPERATION_FAILED
	}

	if core.AdapterInstance == nil {
		logger.Error(ctx, "sysrepo-get-vlans-nil-translator")
		return C.SR_ERR_OPERATION_FAILED
	}

	vlans, err := core.AdapterInstance.GetVlans(ctx)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-vlans-translation-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	err = updateYangTree(ctx, session, parent, vlans)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-vlans-update-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	logger.Info(ctx, "vlans-information-request-served")

	return C.SR_ERR_OK
}

//export get_bandwidth_profiles_cb
func get_bandwidth_profiles_cb(session *C.sr_session_ctx_t, parent **C.lyd_node) C.sr_error_t {
	//This function is a callback for the retrieval of bandwidth profiles from sysrepo
	//The "export" comment instructs CGO to create a C function for it

	ctx := context.Background()
	logger.Debug(ctx, "processing-get-bandwidth-profiles-request")

	if session == nil {
		logger.Error(ctx, "sysrepo-get-bandwidth-profiles-null-session")
		return C.SR_ERR_OPERATION_FAILED
	}

	if parent == nil {
		logger.Error(ctx, "sysrepo-get-bandwidth-profiles-null-parent-node")
		return C.SR_ERR_OPERATION_FAILED
	}

	if core.AdapterInstance == nil {
		logger.Error(ctx, "sysrepo-get-bandwidth-profiles-nil-translator")
		return C.SR_ERR_OPERATION_FAILED
	}

	bwProfiles, err := core.AdapterInstance.GetBandwidthProfiles(ctx)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-bandwidth-profiles-translation-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	err = updateYangTree(ctx, session, parent, bwProfiles)
	if err != nil {
		logger.Errorw(ctx, "sysrepo-get-bandwidth-profiles-update-error", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	logger.Info(ctx, "bandwidth-profiles-information-request-served")

	return C.SR_ERR_OK
}

//export edit_service_profiles_cb
func edit_service_profiles_cb(editSession *C.sr_session_ctx_t, runningSession *C.sr_session_ctx_t, event C.sr_event_t) C.sr_error_t {
	//This function is a callback for changes on service profiles
	//The "export" comment instructs CGO to create a C function for it

	if event != C.SR_EV_CHANGE {
		return C.SR_ERR_OK
	}

	ctx := context.Background()
	logger.Debug(ctx, "processing-service-profile-changes")

	serviceNamesChanges, err := getChangesList(ctx, editSession, core.ServiceProfilesPath+"/service-profile/name")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-names-changes", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	for _, n := range serviceNamesChanges {
		switch n.Operation {
		case C.SR_OP_CREATED:
			if errCode := edit_service_create(ctx, editSession, runningSession, n.Value); errCode != C.SR_ERR_OK {
				return errCode
			}
		case C.SR_OP_DELETED:
			if errCode := edit_service_delete(ctx, editSession, runningSession, n.Value); errCode != C.SR_ERR_OK {
				return errCode
			}
		default:
			return C.SR_ERR_UNSUPPORTED
		}
	}

	return C.SR_ERR_OK
}

func edit_service_create(ctx context.Context, editSession *C.sr_session_ctx_t, runningSession *C.sr_session_ctx_t, serviceName string) C.sr_error_t {
	portName, err := getSingleChangeValue(ctx, editSession, fmt.Sprintf("%s/service-profile[name='%s']/ports/port/name", core.ServiceProfilesPath, serviceName))
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-port-changes", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}

	servicePortPath := core.GetServicePortPath(serviceName, portName)

	tpId, err := getSingleChangeValue(ctx, editSession, servicePortPath+"/bbf-nt-service-profile-voltha:technology-profile-id")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-tp-id-change", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}

	vlanName, err := getSingleChangeValue(ctx, editSession, servicePortPath+"/port-vlans/port-vlan/name")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-vlan-change", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}

	vlansPath := core.GetVlansPath(vlanName)

	sTag, err := getSingleChangeValue(ctx, editSession, vlansPath+"/ingress-rewrite/push-outer-tag/vlan-id")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-stag-changes", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}
	if sTag == core.YangVlanIdAny {
		sTag = strconv.Itoa(core.VolthaVlanIdAny)
	}

	cTag, err := getSingleChangeValue(ctx, editSession, vlansPath+"/ingress-rewrite/push-second-tag/vlan-id")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-stag-changes", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}
	if cTag == core.YangVlanIdAny {
		cTag = strconv.Itoa(core.VolthaVlanIdAny)
	}

	logger.Infow(ctx, "new-service-profile-information", log.Fields{
		"service":  serviceName,
		"port":     portName,
		"vlanName": vlanName,
		"tpId":     tpId,
		"sTag":     sTag,
		"cTag":     cTag,
	})

	if core.AdapterInstance == nil {
		logger.Error(ctx, "sysrepo-service-changes-nil-translator")
		return C.SR_ERR_OPERATION_FAILED
	}

	if err := core.AdapterInstance.ProvisionService(portName, sTag, cTag, tpId); err != nil {
		logger.Errorw(ctx, "service-provisioning-error", log.Fields{
			"service": serviceName,
			"err":     err,
		})
		return C.SR_ERR_OPERATION_FAILED
	}

	logger.Infow(ctx, "service-profile-creation-request-served", log.Fields{
		"service": serviceName,
	})

	return C.SR_ERR_OK
}

func edit_service_delete(ctx context.Context, editSession *C.sr_session_ctx_t, runningSession *C.sr_session_ctx_t, serviceName string) C.sr_error_t {
	portName, err := getDatastoreLeafValue(ctx, runningSession, fmt.Sprintf("%s/service-profile[name='%s']/ports/port/name", core.ServiceProfilesPath, serviceName))
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-port-leaf", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}

	servicePortPath := core.GetServicePortPath(serviceName, portName)

	tpId, err := getDatastoreLeafValue(ctx, runningSession, servicePortPath+"/bbf-nt-service-profile-voltha:technology-profile-id")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-tp-id-leaf", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}

	vlanName, err := getDatastoreLeafValue(ctx, runningSession, servicePortPath+"/port-vlans/port-vlan/name")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-vlan-leaf", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}

	vlansPath := core.GetVlansPath(vlanName)

	sTag, err := getDatastoreLeafValue(ctx, runningSession, vlansPath+"/ingress-rewrite/push-outer-tag/vlan-id")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-stag-leaf", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}
	if sTag == core.YangVlanIdAny {
		sTag = strconv.Itoa(core.VolthaVlanIdAny)
	}

	cTag, err := getDatastoreLeafValue(ctx, runningSession, vlansPath+"/ingress-rewrite/push-second-tag/vlan-id")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-service-profile-stag-leaf", log.Fields{"err": err, "service": serviceName})
		return C.SR_ERR_OPERATION_FAILED
	}
	if cTag == core.YangVlanIdAny {
		cTag = strconv.Itoa(core.VolthaVlanIdAny)
	}

	logger.Infow(ctx, "service-profile-deletion-information", log.Fields{
		"service":  serviceName,
		"port":     portName,
		"vlanName": vlanName,
		"tpId":     tpId,
		"sTag":     sTag,
		"cTag":     cTag,
	})

	if err := core.AdapterInstance.RemoveService(portName, sTag, cTag, tpId); err != nil {
		logger.Errorw(ctx, "service-removal-error", log.Fields{
			"service": serviceName,
			"err":     err,
		})
		return C.SR_ERR_OPERATION_FAILED
	}

	logger.Infow(ctx, "service-profile-removal-request-served", log.Fields{
		"service": serviceName,
	})

	return C.SR_ERR_OK
}

//export edit_vlans_cb
func edit_vlans_cb(editSession *C.sr_session_ctx_t, event C.sr_event_t) C.sr_error_t {
	//This function is a callback for changes on VLANs
	//The "export" comment instructs CGO to create a C function for it

	if event != C.SR_EV_CHANGE {
		return C.SR_ERR_OK
	}

	ctx := context.Background()
	logger.Debug(ctx, "processing-vlans-changes")

	vlanChanges, err := getChangesList(ctx, editSession, core.VlansPath+"//.")
	if err != nil {
		logger.Errorw(ctx, "cannot-get-vlans-changes", log.Fields{"err": err})
		return C.SR_ERR_OPERATION_FAILED
	}

	for _, n := range vlanChanges {
		//VLANs must be defined through creation (for service provisioning)
		//or deletion (for service removal). Changes to the VLAN values
		//are not supported, because VOLTHA does not support dynamic changes
		//to the service.
		switch n.Operation {
		case C.SR_OP_CREATED:
		case C.SR_OP_DELETED:
			//Everything will be handled in the services callback
			//Just approve the change here
			return C.SR_ERR_OK
		default:
			return C.SR_ERR_UNSUPPORTED
		}
	}

	return C.SR_ERR_OK
}
