/*
 * Copyright 2017-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 core

import (
	"context"
	"net"
	"sort"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
	"github.com/opencord/voltha/ponsim/v2/common"
	"github.com/opencord/voltha/protos/go/openflow_13"
	"github.com/sirupsen/logrus"
)

// TODO: Pass-in the certificate information as a structure parameter
// TODO: Add certification information

type PonSimDevice struct {
	Name        string               `json:name`
	Port        int32                `json:port`
	Address     string               `json:address`
	ExternalIf  string               `json:external_if`
	InternalIf  string               `json:internal_if`
	Promiscuous bool                 `json:promiscuous`
	SnapshotLen int32                `json:snapshot_len`
	AlarmsOn    bool                 `json:alarm_on`
	AlarmsFreq  int                  `json:alarm_freq`
	Counter     *PonSimMetricCounter `json:counter`

	//*grpc.GrpcSecurity

	flows          []*openflow_13.OfpFlowStats `json:-`
	ingressHandler *pcap.Handle                `json:-`
	egressHandler  *pcap.Handle                `json:-`
	links          map[int]map[int]interface{} `json:-`
}

const (
	UDP_DST  = 1
	UDP_SRC  = 2
	IPV4_DST = 4
	VLAN_PCP = 8
	VLAN_VID = 16
	IP_PROTO = 32
	ETH_TYPE = 64
	IN_PORT  = 128
)

/*
Start performs common setup operations for a ponsim device
*/
func (o *PonSimDevice) Start(ctx context.Context) {
}

/*
Stop performs common cleanup operations for a ponsim device
*/
func (o *PonSimDevice) Stop(ctx context.Context) {
}

/*
GetAddress returns the IP/FQDN for the device
*/
func (o *PonSimDevice) GetAddress() string {
	return o.Address
}

/*
GetPort return the port assigned to the device
*/
func (o *PonSimDevice) GetPort() int32 {
	return o.Port
}

/*
Forward is responsible of processing incoming data, filtering it and redirecting to the
intended destination
*/
func (o *PonSimDevice) Forward(
	ctx context.Context,
	port int,
	frame gopacket.Packet,
) error {
	common.Logger().WithFields(logrus.Fields{
		"device": o,
		"port":   port,
		"frame":  frame,
	}).Debug("Forwarding packet")

	var err error

	o.Counter.CountRxFrame(port, len(common.GetEthernetLayer(frame).Payload))

	if egressPort, egressFrame := o.processFrame(ctx, port, frame); egressFrame != nil {
		forwarded := 0
		links := o.links[int(egressPort)]

		o.Counter.CountTxFrame(int(egressPort), len(common.GetEthernetLayer(egressFrame).Payload))

		for _, link := range links {
			forwarded += 1

			common.Logger().WithFields(logrus.Fields{
				"device":      o,
				"egressPort":  port,
				"egressFrame": egressFrame,
			}).Debug("Forwarding packet to link")

			link.(func(int, gopacket.Packet))(int(egressPort), egressFrame)
		}
		if forwarded == 0 {
			common.Logger().WithFields(logrus.Fields{
				"device": o,
				"port":   port,
				"frame":  frame,
			}).Warn("Nothing was forwarded")
		}
	} else {
		common.Logger().WithFields(logrus.Fields{
			"device": o,
			"port":   egressPort,
			"frame":  egressFrame,
		}).Error("Failed to properly process frame")
	}

	return err
}

/*
connectNetworkInterfaces opens network interfaces for reading and/or writing packets
*/
func (o *PonSimDevice) connectNetworkInterfaces() {
	common.Logger().WithFields(logrus.Fields{
		"device": o,
	}).Debug("Opening network interfaces")

	var err error
	if o.ingressHandler, err = pcap.OpenLive(
		o.ExternalIf, o.SnapshotLen, o.Promiscuous, pcap.BlockForever,
	); err != nil {
		common.Logger().WithFields(logrus.Fields{
			"device":    o,
			"interface": o.ExternalIf,
			"error":     err.Error(),
		}).Fatal("Unable to open Ingress interface")
	} else {
		common.Logger().WithFields(logrus.Fields{
			"device":    o,
			"interface": o.ExternalIf,
		}).Info("Opened Ingress interface")
	}

	if o.egressHandler, err = pcap.OpenLive(
		o.InternalIf, o.SnapshotLen, o.Promiscuous, pcap.BlockForever,
	); err != nil {
		common.Logger().WithFields(logrus.Fields{
			"device":    o,
			"interface": o.InternalIf,
			"error":     err.Error(),
		}).Fatal("Unable to open egress interface")
	} else {
		common.Logger().WithFields(logrus.Fields{
			"device":    o,
			"interface": o.InternalIf,
		}).Info("Opened egress interface")
	}
}

/*
AddLink assigns a functional operation to a device endpoint

The functional operation is called whenever a packet has been processed
and the endpoint has been identified as the outgoing interface
*/
func (o *PonSimDevice) AddLink(
	port int,
	index int,
	function interface{},
) error {
	common.Logger().WithFields(logrus.Fields{
		"device": o,
		"port":   port,
		"index":  index,
	}).Debug("Linking port to functional operation")

	if o.links == nil {
		o.links = make(map[int]map[int]interface{})
	}
	if _, ok := o.links[port]; !ok {
		o.links[port] = make(map[int]interface{})
	}
	o.links[port][index] = function

	return nil
}

/*
RemoveLink will remove reference a functional operation for a given port and index
*/
func (o *PonSimDevice) RemoveLink(
	port int,
	index int,
) error {
	if _, hasPort := o.links[port]; hasPort {
		if _, hasIndex := o.links[port][index]; hasIndex {
			common.Logger().WithFields(logrus.Fields{
				"device": o,
				"port":   port,
				"index":  index,
			}).Debug("Removing link functional operation")

			delete(o.links[port], index)

		} else {
			common.Logger().WithFields(logrus.Fields{
				"device": o,
				"port":   port,
				"index":  index,
			}).Warn("No such index for link functional operation")

		}
	} else {
		common.Logger().WithFields(logrus.Fields{
			"device": o,
			"port":   port,
			"index":  index,
		}).Warn("No such port for functional operation")
	}

	return nil
}

/*
InstallFlows assigns flows to the device in order of priority
*/
func (o *PonSimDevice) InstallFlows(
	ctx context.Context,
	flows []*openflow_13.OfpFlowStats,
) error {
	common.Logger().WithFields(logrus.Fields{
		"device": o,
		"flows":  flows,
	}).Debug("Installing flows")

	o.flows = flows
	sort.Sort(sort.Reverse(common.SortByPriority(o.flows)))

	common.Logger().WithFields(logrus.Fields{
		"device": o,
	}).Debug("Installed sorted flows")

	return nil
}

/*
processFrame is responsible for matching or discarding a frame based on the configured flows
*/
func (o *PonSimDevice) processFrame(
	ctx context.Context,
	port int,
	frame gopacket.Packet,
) (uint32, gopacket.Packet) {
	common.Logger().WithFields(logrus.Fields{
		"device": o,
		"port":   port,
		"frame":  frame,
	}).Debug("Processing frame")

	var err error
	var matchedMask int = 0
	var currentMask int
	var highestPriority uint32 = 0
	var matchedFlow *openflow_13.OfpFlowStats = nil

	common.Logger().WithFields(logrus.Fields{
		"device": o,
	}).Debug("Looping through flows")

	for _, flow := range o.flows {
		common.Logger().WithFields(logrus.Fields{
			"device": o,
			"flow":   flow,
		}).Debug("Checking flow")

		if matchedFlow != nil && flow.Priority < highestPriority {
			common.Logger().WithFields(logrus.Fields{
				"device":      o,
				"matchedFlow": matchedFlow,
				"priority":    highestPriority,
			}).Debug("Flow has already been matched")
			break
		} else {
			common.Logger().WithFields(logrus.Fields{
				"device":          o,
				"matchedFlow":     matchedFlow,
				"priority":        flow.Priority,
				"highestPriority": highestPriority,
			}).Debug("Flow OR Priority requirements not met")
		}

		highestPriority = flow.Priority
		if currentMask, err = o.isMatch(ctx, flow, port, frame); err != nil {
			common.Logger().WithFields(logrus.Fields{
				"device": o,
				"flow":   flow,
				"port":   port,
				"frame":  frame,
				"error":  err.Error(),
			}).Error("Problem while matching flow")

		} else if currentMask > matchedMask {
			matchedMask = currentMask
			matchedFlow = flow

			common.Logger().WithFields(logrus.Fields{
				"device":      o,
				"matchedFlow": flow,
				"port":        port,
				"frame":       frame,
				"matchedMask": matchedMask,
			}).Debug("Flow matches")
		}
	}

	if matchedFlow != nil {
		egressPort, egressFrame := o.processActions(ctx, matchedFlow, frame)

		common.Logger().WithFields(logrus.Fields{
			"device":      o,
			"port":        port,
			"egressPort":  egressPort,
			"egressFrame": egressFrame,
		}).Debug("Processed actions to matched flow")

		return egressPort, egressFrame
	} else {
		common.Logger().WithFields(logrus.Fields{
			"device":      o,
			"port":        port,
			"frame":       frame,
			"matchedMask": matchedMask,
		}).Warn("Flow was not successfully matched")
	}

	return 0, nil
}

/*
isMatch traverses the criteria of a flow and identify all matching elements of a frame (if any)
*/
func (o *PonSimDevice) isMatch(
	ctx context.Context,
	flow *openflow_13.OfpFlowStats,
	port int,
	frame gopacket.Packet,
) (int, error) {
	matchedMask := 0

	for _, ofbfield := range flow.Match.OxmFields {
		if ofbfield.GetOxmClass() == openflow_13.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
			switch ofbfield.GetOfbField().Type {
			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
				if ofbfield.GetOfbField().GetPort() != uint32(port) {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetPort(),
						"actual":   port,
					}).Warn("Port does not match")
					return 0, nil
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetPort(),
						"actual":   port,
					}).Debug("Port matches")
				}
				matchedMask |= IN_PORT

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
				cmpType := uint32(common.GetEthernetLayer(frame).EthernetType)
				if dot1q := common.GetDot1QLayer(frame); dot1q != nil {
					cmpType = uint32(dot1q.Type)
				}
				if ofbfield.GetOfbField().GetEthType() != cmpType {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": layers.EthernetType(ofbfield.GetOfbField().GetEthType()),
						"actual":   common.GetEthernetLayer(frame).EthernetType,
					}).Warn("Frame type does not match")
					return 0, nil
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": layers.EthernetType(ofbfield.GetOfbField().GetEthType()),
						"actual":   common.GetEthernetLayer(frame).EthernetType,
					}).Debug("Frame type matches")
				}
				matchedMask |= ETH_TYPE

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
				if ofbfield.GetOfbField().GetIpProto() != uint32(common.GetIpLayer(frame).Protocol) {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetIpProto(),
						"actual":   common.GetIpLayer(frame).Protocol,
					}).Warn("IP protocol does not match")
					return 0, nil
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetIpProto(),
						"actual":   common.GetIpLayer(frame).Protocol,
					}).Debug("IP protocol matches")
				}
				matchedMask |= IP_PROTO

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
				expectedVlan := ofbfield.GetOfbField().GetVlanVid()
				dot1q := common.GetDot1QLayer(frame)

				if (expectedVlan&4096 == 0) != (dot1q == nil) {
					common.Logger().WithFields(logrus.Fields{
						"device":       o,
						"flow":         flow,
						"expectedVlan": expectedVlan,
						"vlanBitwise":  expectedVlan & 4096,
						"dot1q":        dot1q,
					}).Warn("VLAN condition not met")
					return 0, nil
				}
				if dot1q != nil {
					if uint32(dot1q.VLANIdentifier) != (expectedVlan & 4095) {
						common.Logger().WithFields(logrus.Fields{
							"device":   o,
							"flow":     flow,
							"expected": expectedVlan,
							"actual":   uint32(dot1q.VLANIdentifier),
						}).Warn("VLAN VID does not match")
						return 0, nil
					} else {
						common.Logger().WithFields(logrus.Fields{
							"device":   o,
							"flow":     flow,
							"expected": expectedVlan,
							"actual":   uint32(dot1q.VLANIdentifier),
						}).Debug("VLAN VID matches")
					}
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device": o,
						"flow":   flow,
					}).Warn("VLAN VID missing. Not dot1q encapsulation")
				}
				matchedMask |= VLAN_VID

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
				if ofbfield.GetOfbField().GetVlanPcp() != uint32(common.GetDot1QLayer(frame).Priority) {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetVlanPcp(),
						"actual":   uint32(common.GetDot1QLayer(frame).Priority),
					}).Warn("VLAN priority does not match")
					return 0, nil
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetVlanPcp(),
						"actual":   uint32(common.GetDot1QLayer(frame).Priority),
					}).Debug("VLAN priority matches")
				}
				matchedMask |= VLAN_PCP

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
				dstIpRaw := ofbfield.GetOfbField().GetIpv4Dst()
				dstIp := net.IPv4(
					byte((dstIpRaw>>24)&0xFF),
					byte((dstIpRaw>>16)&0xFF),
					byte((dstIpRaw>>8)&0xFF),
					byte(dstIpRaw&0xFF))

				if !dstIp.Equal(common.GetIpLayer(frame).DstIP) {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": dstIp,
						"actual":   common.GetIpLayer(frame).DstIP,
					}).Warn("IPv4 destination does not match")
					return 0, nil
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": dstIp,
						"actual":   common.GetIpLayer(frame).DstIP,
					}).Debug("IPv4 destination matches")

				}
				matchedMask |= IPV4_DST

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
				if ofbfield.GetOfbField().GetUdpSrc() != uint32(common.GetUdpLayer(frame).SrcPort) {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetUdpSrc(),
						"actual":   common.GetUdpLayer(frame).SrcPort,
					}).Warn("UDP source port does not match")
					return 0, nil
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetUdpSrc(),
						"actual":   common.GetUdpLayer(frame).SrcPort,
					}).Debug("UDP source port matches")
				}
				matchedMask |= UDP_SRC

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
				if ofbfield.GetOfbField().GetUdpDst() != uint32(common.GetUdpLayer(frame).DstPort) {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetUdpDst(),
						"actual":   common.GetUdpLayer(frame).DstPort,
					}).Warn("UDP destination port does not match")
					return 0, nil
				} else {
					common.Logger().WithFields(logrus.Fields{
						"device":   o,
						"flow":     flow,
						"expected": ofbfield.GetOfbField().GetUdpDst(),
						"actual":   common.GetUdpLayer(frame).DstPort,
					}).Debug("UDP destination port does matches")
				}
				matchedMask |= UDP_DST

			case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
				common.Logger().WithFields(logrus.Fields{
					"device": o,
					"flow":   flow,
				}).Warn("Skipping metadata")
				continue

			default:
				common.Logger().WithFields(logrus.Fields{
					"device": o,
					"flow":   flow,
					"type":   ofbfield.GetOfbField().Type,
				}).Warn("Field type not implemented")
			}
		}
	}
	return matchedMask, nil
}

/*
processActions applies transformation instructions to a frame that met all the flow criteria
*/
func (o *PonSimDevice) processActions(
	ctx context.Context,
	flow *openflow_13.OfpFlowStats,
	frame gopacket.Packet,
) (uint32, gopacket.Packet) {
	var egressPort uint32
	var retFrame gopacket.Packet = frame

	common.Logger().WithFields(logrus.Fields{
		"device": o,
		"flow":   flow,
		"frame":  retFrame,
	}).Info("Processing actions")

	for _, instruction := range flow.Instructions {
		common.Logger().WithFields(logrus.Fields{
			"device":      o,
			"flow":        flow,
			"frame":       retFrame,
			"instruction": instruction,
		}).Debug("Processing actions - Instruction entry")
		if instruction.Type == uint32(openflow_13.OfpInstructionType_OFPIT_APPLY_ACTIONS) {
			for _, action := range instruction.GetActions().GetActions() {
				common.Logger().WithFields(logrus.Fields{
					"device":     o,
					"flow":       flow,
					"frame":      retFrame,
					"action":     action,
					"actionType": action.Type,
				}).Debug("Processing actions - Action entry")

				switch action.Type {
				case openflow_13.OfpActionType_OFPAT_OUTPUT:
					common.Logger().WithFields(logrus.Fields{
						"device": o,
						"flow":   flow,
						"frame":  retFrame,
					}).Debug("Processing action OFPAT output")
					egressPort = action.GetOutput().Port

				case openflow_13.OfpActionType_OFPAT_POP_VLAN:
					common.Logger().WithFields(logrus.Fields{
						"device": o,
						"flow":   flow,
						"frame":  retFrame,
					}).Debug("Processing action OFPAT POP VLAN")
					if shim := common.GetDot1QLayer(retFrame); shim != nil {
						if eth := common.GetEthernetLayer(retFrame); eth != nil {
							ethernetLayer := &layers.Ethernet{
								SrcMAC:       eth.SrcMAC,
								DstMAC:       eth.DstMAC,
								EthernetType: shim.Type,
							}
							buffer := gopacket.NewSerializeBuffer()
							gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
								ethernetLayer,
								gopacket.Payload(shim.Payload),
							)
							retFrame = gopacket.NewPacket(
								buffer.Bytes(),
								layers.LayerTypeEthernet,
								gopacket.Default,
							)
						} else {
							common.Logger().WithFields(logrus.Fields{
								"device": o,
								"flow":   flow,
								"frame":  retFrame,
							}).Warn("No ETH found while processing POP VLAN action")
						}
					} else {
						common.Logger().WithFields(logrus.Fields{
							"device": o,
							"flow":   flow,
							"frame":  retFrame,
						}).Warn("No DOT1Q found while processing POP VLAN action")
					}
				case openflow_13.OfpActionType_OFPAT_PUSH_VLAN:
					if eth := common.GetEthernetLayer(retFrame); eth != nil {
						ethernetLayer := &layers.Ethernet{
							SrcMAC:       eth.SrcMAC,
							DstMAC:       eth.DstMAC,
							EthernetType: layers.EthernetType(action.GetPush().GetEthertype()),
						}
						dot1qLayer := &layers.Dot1Q{
							Type: eth.EthernetType,
						}

						buffer := gopacket.NewSerializeBuffer()
						gopacket.SerializeLayers(
							buffer,
							gopacket.SerializeOptions{
								FixLengths: false,
							},
							ethernetLayer,
							dot1qLayer,
							gopacket.Payload(eth.Payload),
						)
						retFrame = gopacket.NewPacket(
							buffer.Bytes(),
							layers.LayerTypeEthernet,
							gopacket.Default,
						)
					} else {
						common.Logger().WithFields(logrus.Fields{
							"device": o,
							"flow":   flow,
							"frame":  retFrame,
						}).Warn("No ETH found while processing PUSH VLAN action")
					}
				case openflow_13.OfpActionType_OFPAT_SET_FIELD:
					common.Logger().WithFields(logrus.Fields{
						"device": o,
						"flow":   flow,
						"frame":  retFrame,
					}).Debug("Processing action OFPAT SET FIELD")
					if action.GetSetField().GetField().GetOxmClass() ==
						openflow_13.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
						field := action.GetSetField().GetField().GetOfbField()

						switch field.Type {
						case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
							common.Logger().WithFields(logrus.Fields{
								"device": o,
								"flow":   flow,
								"frame":  retFrame,
							}).Debug("Processing action OFPAT SET FIELD - VLAN VID")
							if shim := common.GetDot1QLayer(retFrame); shim != nil {
								eth := common.GetEthernetLayer(retFrame)
								buffer := gopacket.NewSerializeBuffer()

								var dot1qLayer *layers.Dot1Q
								var ethernetLayer *layers.Ethernet
								ethernetLayer = &layers.Ethernet{
									SrcMAC:       eth.SrcMAC,
									DstMAC:       eth.DstMAC,
									EthernetType: eth.EthernetType,
								}

								dot1qLayer = &layers.Dot1Q{
									Type:           shim.Type,
									VLANIdentifier: uint16(field.GetVlanVid() & 4095),
								}

								gopacket.SerializeLayers(
									buffer,
									gopacket.SerializeOptions{},
									ethernetLayer,
									dot1qLayer,
									gopacket.Payload(shim.LayerPayload()),
								)
								retFrame = gopacket.NewPacket(
									buffer.Bytes(),
									layers.LayerTypeEthernet,
									gopacket.Default,
								)

								common.Logger().WithFields(logrus.Fields{
									"device":    o,
									"flow":      flow,
									"frame":     retFrame,
									"frameDump": retFrame.Dump(),
									"vlanVid":   shim.VLANIdentifier,
								}).Info("Setting DOT1Q VLAN VID")
							} else {
								common.Logger().WithFields(logrus.Fields{
									"device": o,
									"flow":   flow,
									"frame":  retFrame,
								}).Warn("No DOT1Q found while setting VLAN VID")
							}

						case openflow_13.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
							common.Logger().WithFields(logrus.Fields{
								"device": o,
								"flow":   flow,
								"frame":  retFrame,
							}).Debug("Processing action OFPAT SET FIELD - VLAN PCP")
							if shim := common.GetDot1QLayer(retFrame); shim != nil {
								shim.Priority = uint8(field.GetVlanPcp())
								common.Logger().WithFields(logrus.Fields{
									"device":   o,
									"flow":     flow,
									"frame":    retFrame,
									"priority": shim.Priority,
								}).Info("Setting DOT1Q VLAN PCP")
							} else {
								common.Logger().WithFields(logrus.Fields{
									"device": o,
									"flow":   flow,
									"frame":  retFrame,
								}).Warn("No DOT1Q found while setting VLAN PCP")
							}
						default:
							common.Logger().WithFields(logrus.Fields{
								"device": o,
								"flow":   flow,
								"frame":  retFrame,
								"type":   field.Type,
							}).Warn("Set field not implemented for this type")
						}
					} else {
						common.Logger().WithFields(logrus.Fields{
							"device": o,
							"flow":   flow,
							"frame":  retFrame,
						}).Warn("Field not of type OF-BASIC")
					}
				default:
					common.Logger().WithFields(logrus.Fields{
						"device": o,
						"flow":   flow,
						"frame":  retFrame,
						"type":   action.Type,
					}).Warn("Action type not implemented")
				}
			}
		}
	}

	common.Logger().WithFields(logrus.Fields{
		"device":     o,
		"flow":       flow,
		"egressPort": egressPort,
		"retFrame":   retFrame,
	}).Debug("Processed actions")

	return egressPort, retFrame
}
