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

import (
	"context"
	"net"
	"strconv"

	"github.com/google/gopacket/layers"

	"github.com/opencord/voltha-lib-go/v7/pkg/flows"
	"voltha-go-controller/log"
	ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
	//"github.com/opencord/voltha-protos/v5/go/voltha"
)

// PbitType type
type PbitType uint16

// TODO: Port related constants - OF specifies a different value
// for controller. Need to make sure this is correct
const (
	ControllerPort uint32   = 0xfffffffd
	PbitMatchNone  PbitType = 8
	PbitMatchAll   PbitType = 0xFF
)

var logger log.CLogger
var ctx = context.TODO()

// ----------------------------------------------------------
// Cookie related specifications and utilities
// ----------------------------------------------------------
// Though the openflow does not utilize cookies as unique identities of
// flows, we use cookies as identities in the application. The same
// may also be used in the VOLTHA if so desired to reduce the complexity
// of management of flows. In terms of how the cookie is set and is
// ensured to be unique is:
// Cookie is a 64 bit value. The first 32 bits are set to the port-id
// All rules set at the device level are associated with NNI. All other
// flows, both ingress and egress are associated with the access port.
// The last 32 bits are used to uniquely identifies flows of a port.
const (
	// The flow masks are used to set the MSB of the lower
	// 32 bits of cookie

	// UsFlowMask constant
	UsFlowMask uint64 = 0x8000
	// DsFlowMask constant
	DsFlowMask uint64 = 0x0000

	// Flow types used to divide the available cookie value range
	// Each type is allocated 256 flow identities which are plenty
	// for the known use cases.

	// DhcpArpFlowMask constant
	DhcpArpFlowMask uint64 = 0x0100
	// PppoeFlowMask constant
	PppoeFlowMask uint64 = 0x0100
	// HsiaFlowMask constant
	HsiaFlowMask uint64 = 0x0200
	// DsArpFlowMask constant
	DsArpFlowMask uint64 = 0x0300
	// IgmpFlowMask constant
	IgmpFlowMask uint64 = 0x0400
	// Dhcpv6FlowMask constant
	Dhcpv6FlowMask uint64 = 0x0800

	// Flow priorities - Higher the value, higher the priority

	// DhcpFlowPriority constant
	DhcpFlowPriority uint32 = 5000
	// ArpFlowPriority constant
	ArpFlowPriority uint32 = 5000
	// IgmpFlowPriority constant
	IgmpFlowPriority uint32 = 5000
	// McFlowPriority constant
	McFlowPriority uint32 = 5000
	// PppoeFlowPriority constant
	PppoeFlowPriority uint32 = 5000
	// HsiaFlowPriority constant
	HsiaFlowPriority uint32 = 100
)

// CookieSetPort to set port
func CookieSetPort(cookie uint64, port uint32) uint64 {
	return cookie | (uint64(port) << 32)
}

// CookieGetPort to get port
func CookieGetPort(cookie uint64) uint32 {
	return uint32(cookie >> 32)
}

// -------------------------------------------------------
// The flow match and action related definitions follow
// -------------------------------------------------------
// The Ethernet types listed below serve our requirement. We may extend
// the list as we identify more use cases to be supported.

// EtherType type
type EtherType uint16

const (
	// EtherTypeAny constant
	EtherTypeAny EtherType = 0x0000 // Needs assertion
	// EtherTypeIpv4 constant
	EtherTypeIpv4 EtherType = 0x0800
	// EtherTypeIpv6 constant
	EtherTypeIpv6 EtherType = 0x86DD
	// EtherTypePppoeDiscovery constant
	EtherTypePppoeDiscovery EtherType = 0x8863
	// EtherTypePppoeSession constant
	EtherTypePppoeSession EtherType = 0x8864
	// EtherTypeArp constant
	EtherTypeArp EtherType = 0x0806
)

// VLAN related definitions
// VLANs can take a value between 1 and 4095. VLAN 0 is used to set just
// the PCP bytes. VLAN 4097 is being used to represent "no VLAN"
// 4096 is being used to represent "any vlan"

// VlanType type
type VlanType uint16

const (
	// VlanAny constant
	VlanAny VlanType = 0x1000
	// VlanNone constant
	VlanNone VlanType = 0x1001
)

func (vlan *VlanType) String() string {
	return strconv.Itoa(int(*vlan))
}

// IP Protocol defintions
// IP protocol 0xff is reserved and we are using the reserved value to
// represent that match is not needed.

// IPProtocol type
type IPProtocol uint8

const (
	// IPProtocolIgnore constant
	IPProtocolIgnore IPProtocol = 0xff
	// IPProtocolTCP constant
	IPProtocolTCP IPProtocol = 0x06
	// IPProtocolUDP constant
	IPProtocolUDP IPProtocol = 0x11
	// IPProtocolIgmp constant
	IPProtocolIgmp IPProtocol = 0x02
	// IPProtocolIcmpv6 constant
	IPProtocolIcmpv6 IPProtocol = 0x3A
)

// The following structure is included in each flow which further is
// used to create a flow. The match structure is used to specify the
// match rules encoded into the flow.

// Match structure
type Match struct {
	InPort        uint32
	MatchVlan     VlanType
	SrcMacMatch   bool
	SrcMacAddr    net.HardwareAddr
	SrcMacMask    net.HardwareAddr
	DstMacMatch   bool
	DstMacAddr    net.HardwareAddr
	DstMacMask    net.HardwareAddr
	MatchPbits    bool
	Pbits         PbitType
	L3Protocol    EtherType
	SrcIpv4Match  bool
	SrcIpv4Addr   net.IP
	DstIpv4Match  bool
	DstIpv4Addr   net.IP
	L4Protocol    IPProtocol
	SrcPort       uint16
	DstPort       uint16
	TableMetadata uint64
}

// Reset to be used when a Match is created. It sets the values to
// defaults which results is no match rules at all and thus when
// applied on a port, match all packets. The match rules must be
// set before use.
func (m *Match) Reset() {
	m.MatchVlan = VlanNone
	m.SrcMacMatch = false
	m.DstMacMatch = false
	m.MatchPbits = false
	m.L3Protocol = EtherTypeAny
	m.L4Protocol = IPProtocolIgnore
	m.SrcPort = 0
	m.DstPort = 0
	m.TableMetadata = 0
}

// SetInPort to set in port
func (m *Match) SetInPort(port uint32) {
	m.InPort = port
}

// SetMatchVlan to set match vlan
func (m *Match) SetMatchVlan(vlan VlanType) {
	m.MatchVlan = vlan
}

// SetPppoeDiscoveryMatch to set L3 protocol
func (m *Match) SetPppoeDiscoveryMatch() {
	m.L3Protocol = EtherTypePppoeDiscovery
}

// SetTableMetadata to set table metadata
func (m *Match) SetTableMetadata(metadata uint64) {
	m.TableMetadata = metadata
}

// SetMatchSrcMac to set source mac address
func (m *Match) SetMatchSrcMac(mac net.HardwareAddr) {
	m.SrcMacMatch = true
	m.SrcMacAddr = mac
}

// SetMatchDstMac to set destination mac address
func (m *Match) SetMatchDstMac(mac net.HardwareAddr) {
	m.DstMacMatch = true
	m.DstMacAddr = mac
}

// SetMatchPbit to set pbits
func (m *Match) SetMatchPbit(pbit PbitType) {
	m.MatchPbits = true
	m.Pbits = pbit
}

// SetMatchSrcIpv4 to set source ipv4 address
func (m *Match) SetMatchSrcIpv4(ip net.IP) {
	m.SrcIpv4Match = true
	m.SrcIpv4Addr = ip
}

// SetMatchDstIpv4 to set destination ipv4 address
func (m *Match) SetMatchDstIpv4(ip net.IP) {
	m.DstIpv4Match = true
	m.DstIpv4Addr = ip
}

// SetArpMatch to set L3 protocol as Arp
func (m *Match) SetArpMatch() {
	m.L3Protocol = EtherTypeArp
}

// SetICMPv6Match to set L3 and L4 protocol as IPV6 and ICMPv6
func (m *Match) SetICMPv6Match() {
	m.L3Protocol = EtherTypeIpv6
	m.L4Protocol = IPProtocolIcmpv6
}

// SetUdpv4Match to set L3 and L4 protocol as IPv4 and UDP
func (m *Match) SetUdpv4Match() {
	m.L3Protocol = EtherTypeIpv4
	m.L4Protocol = IPProtocolUDP
}

// SetIgmpMatch to set L3 and L4 protocol as IPv4 and Igmp
func (m *Match) SetIgmpMatch() {
	m.L3Protocol = EtherTypeIpv4
	m.L4Protocol = IPProtocolIgmp
}

// SetUdpv6Match to set L3 and L4 protocol as IPv6 and UDP
func (m *Match) SetUdpv6Match() {
	m.L3Protocol = EtherTypeIpv6
	m.L4Protocol = IPProtocolUDP
}

// SetIpv4Match to set L3 as IPv4
func (m *Match) SetIpv4Match() {
	m.L3Protocol = EtherTypeIpv4
}

// OutputType type
type OutputType uint8

const (
	// OutputTypeDrop constant
	OutputTypeDrop OutputType = 1
	// OutputTypeToController constant
	OutputTypeToController OutputType = 2
	// OutputTypeToNetwork constant
	OutputTypeToNetwork OutputType = 3
	// OutputTypeGoToTable constant
	OutputTypeGoToTable OutputType = 4
	// OutputTypeToGroup constant
	OutputTypeToGroup OutputType = 5
)

const (
	// FlowAddSuccess constant
	FlowAddSuccess = 0
	// FlowAddFailure constant
	FlowAddFailure = 1
	// FlowAddPending constant
	FlowAddPending = 2
	// FlowDelPending constant
	FlowDelPending = 3
	// FlowDelFailure constant
	FlowDelFailure = 4
)

// Action structure
type Action struct {
	Output      OutputType
	PushVlan    []VlanType
	EtherType   layers.EthernetType
	SetVlan     VlanType
	RemoveVlan  int
	OutPort     uint32
	GoToTableID uint32
	Metadata    uint64
	MeterID     uint32
	Pcp         PbitType
}

const (
	// PbitNone constant
	PbitNone PbitType = 8
)

// Reset the action structure
func (a *Action) Reset() {
	a.Output = OutputTypeDrop
	a.PushVlan = make([]VlanType, 0)
	a.SetVlan = VlanNone
	a.RemoveVlan = 0
	a.Metadata = 0
	a.MeterID = 0
	a.Pcp = PbitNone
}

// SetReportToController for set action to report to controller
func (a *Action) SetReportToController() {
	a.Output = OutputTypeToController
	a.OutPort = ControllerPort
}

// SetPushVlan for set action to push to vlan
func (a *Action) SetPushVlan(vlan VlanType, etherType layers.EthernetType) {
	a.PushVlan = append(a.PushVlan, vlan)
	a.EtherType = etherType
}

// SetSetVlan to set SetVlan
func (a *Action) SetSetVlan(vlan VlanType) {
	a.SetVlan = vlan
}

// SetPopVlan to set remove vlan counter
func (a *Action) SetPopVlan() {
	a.RemoveVlan++
}

// SetMeterID to set meter id
func (a *Action) SetMeterID(meterID uint32) {
	a.MeterID = meterID
}

// SetWriteMetadata to set metadata
func (a *Action) SetWriteMetadata(metadata uint64) {
	a.Metadata = metadata
}

// SetPcp to set pcp
func (a *Action) SetPcp(pcp PbitType) {
	a.Pcp = pcp
}

// GetWriteMetadata returns metadata
func (a *Action) GetWriteMetadata() uint64 {
	return a.Metadata
}

// SetOutPort to set output port
func (a *Action) SetOutPort(port uint32) {
	a.Output = OutputTypeToNetwork
	a.OutPort = port
}

// SetOutGroup to set output group
func (a *Action) SetOutGroup(group uint32) {
	a.Output = OutputTypeToGroup
	a.OutPort = group
}

// SetGoToTable to set GoToTableID
func (a *Action) SetGoToTable(table uint32) {
	a.Output = OutputTypeGoToTable
	a.GoToTableID = table
}

// VoltSubFlow structure
type VoltSubFlow struct {
	Cookie     uint64
	CookieMask uint64
	// OldCookie is used in vgc upgrade when there is cookie generation logic change.
	OldCookie   uint64
	TableID     uint32
	Priority    uint32
	State       uint8
	ErrorReason string
	Match
	Action
}

// NewVoltSubFlow is constructor for VoltSubFlow
func NewVoltSubFlow() *VoltSubFlow {
	var sf VoltSubFlow
	sf.Match.Reset()
	sf.Action.Reset()
	return &sf
}

// SetTableID to set table id
func (sf *VoltSubFlow) SetTableID(tableID uint32) {
	sf.TableID = tableID
}

// Command type
type Command uint8

const (
	// CommandAdd constant
	CommandAdd Command = 0
	// CommandDel constant
	CommandDel Command = 1
)

// VoltFlow : Definition of a flow
type VoltFlow struct {
	Command       Command
	SubFlows      map[uint64]*VoltSubFlow
	ForceAction   bool
	MigrateCookie bool
	// PortName and PortID to be used for validation of port before flow pushing
	PortName string
	PortID   uint32
}

const (
	// PrevBwInfo indicates the string returned by core for bandwidth consumed before creating scheduler
	PrevBwInfo string = "prevBW"
	// PresentBwInfo indicates the string returned by core for bandwidth consumed after creating scheduler
	PresentBwInfo string = "presentBW"
)

// BwAvailDetails consists of bw consumtion details at olt
type BwAvailDetails struct {
	PrevBw    string
	PresentBw string
}

// -------------------------------------------------------------------
// OPENFLOW Implementation of flows
//
// The flows constructed using the above structures is translated to
// the VOLTHA OpenFlow GRPC structures. The code below is used to
// construct the VOLTHA OF GRPC structures.
const (
	// DefaultMeterID constant
	DefaultMeterID uint32 = 0x1
	// DefaultBufferID constant
	DefaultBufferID uint32 = 0xffffffff
	// DefaultOutPort constant
	DefaultOutPort uint32 = 0xffffffff
	// DefaultOutGroup constant
	DefaultOutGroup uint32 = 0xffffffff
	// DefaultFlags constant
	DefaultFlags uint32 = 0x1
)

// NewInportMatch for inport info
func NewInportMatch(port uint32) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_Port{Port: port}
	return &entry
}

// NewTableMetadataMatch for table metadata
func NewTableMetadataMatch(metadata uint64) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_METADATA
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_TableMetadata{TableMetadata: metadata}
	return &entry
}

// NewSrcMacAddrMatch for source mac address info
func NewSrcMacAddrMatch(addr []byte) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_SRC
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_EthSrc{EthSrc: addr}
	return &entry
}

// NewDstMacAddrMatch for destination mac address info
func NewDstMacAddrMatch(addr []byte) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_DST
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_EthDst{EthDst: addr}
	return &entry
}

// NewVlanMatch for vlan info
func NewVlanMatch(vlan uint16) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_VlanVid{VlanVid: uint32(vlan&0x0fff + 0x1000)}
	mf.Mask = &ofp.OfpOxmOfbField_VlanVidMask{VlanVidMask: uint32(0x1000)}
	return &entry
}

// NewPcpMatch for pcp info
func NewPcpMatch(pbits PbitType) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_VlanPcp{VlanPcp: uint32(pbits)}
	return &entry
}

// NewEthTypeMatch for eth type info
func NewEthTypeMatch(l3proto uint16) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_EthType{EthType: uint32(l3proto)}
	return &entry
}

// ipv4ToUint to convert ipv4 to uint
func ipv4ToUint(ip net.IP) uint32 {
	result := uint32(0)
	addr := ip.To4()
	if addr == nil {
		logger.Warnw(ctx, "Invalid Group Addr", log.Fields{"IP": ip})
		return 0
	}
	result = result + uint32(addr[0])<<24
	result = result + uint32(addr[1])<<16
	result = result + uint32(addr[2])<<8
	result = result + uint32(addr[3])
	return result
}

// NewIpv4SrcMatch for ipv4 source address
func NewIpv4SrcMatch(ip net.IP) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_Ipv4Src{Ipv4Src: ipv4ToUint(ip)}
	return &entry
}

// NewIpv4DstMatch for ipv4 destination address
func NewIpv4DstMatch(ip net.IP) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_Ipv4Dst{Ipv4Dst: ipv4ToUint(ip)}
	return &entry
}

// NewIPProtoMatch for ip proto info
func NewIPProtoMatch(l4proto uint16) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_IpProto{IpProto: uint32(l4proto)}
	return &entry
}

// NewUDPSrcMatch for source udp info
func NewUDPSrcMatch(port uint16) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_UdpSrc{UdpSrc: uint32(port)}
	return &entry
}

// NewUDPDstMatch for destination udp info
func NewUDPDstMatch(port uint16) *ofp.OfpOxmField {
	var entry ofp.OfpOxmField
	var mf ofp.OfpOxmOfbField
	entry.OxmClass = ofp.OfpOxmClass_OFPXMC_OPENFLOW_BASIC
	entry.Field = &ofp.OfpOxmField_OfbField{OfbField: &mf}
	mf.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST
	mf.HasMask = false
	mf.Value = &ofp.OfpOxmOfbField_UdpDst{UdpDst: uint32(port)}
	return &entry
}

// NewMeterIDInstruction for meter id instructions
func NewMeterIDInstruction(meterID uint32) *ofp.OfpInstruction {
	var meter ofp.OfpInstruction
	meter.Type = uint32(ofp.OfpInstructionType_OFPIT_METER)
	meter.Data = &ofp.OfpInstruction_Meter{
		Meter: &ofp.OfpInstructionMeter{
			MeterId: meterID,
		},
	}
	return &meter
}

// NewGoToTableInstruction for go to table instructions
func NewGoToTableInstruction(table uint32) *ofp.OfpInstruction {
	var gotoTable ofp.OfpInstruction
	gotoTable.Type = uint32(ofp.OfpInstructionType_OFPIT_GOTO_TABLE)
	gotoTable.Data = &ofp.OfpInstruction_GotoTable{
		GotoTable: &ofp.OfpInstructionGotoTable{
			TableId: table,
		},
	}
	return &gotoTable
}

// NewPopVlanInstruction for pop vlan instructions
func NewPopVlanInstruction() *ofp.OfpInstruction {
	var removeTag ofp.OfpInstruction
	var actions ofp.OfpInstructionActions
	removeTag.Type = uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS)
	removeTag.Data = &ofp.OfpInstruction_Actions{
		Actions: &actions,
	}
	action := flows.PopVlan()
	actions.Actions = append(actions.Actions, action)
	return &removeTag
}

// NewWriteMetadataInstruction for write metadata instructions
func NewWriteMetadataInstruction(metadata uint64) *ofp.OfpInstruction {
	var md ofp.OfpInstruction
	md.Type = uint32(ofp.OfpInstructionType_OFPIT_WRITE_METADATA)
	md.Data = &ofp.OfpInstruction_WriteMetadata{WriteMetadata: &ofp.OfpInstructionWriteMetadata{Metadata: metadata}}
	return &md
}

// NewPopVlanAction for pop vlan action
func NewPopVlanAction() *ofp.OfpAction {
	return flows.PopVlan()
}

// NewPushVlanInstruction for push vlan instructions
func NewPushVlanInstruction(vlan uint16, etherType uint32) *ofp.OfpInstruction {
	var addTag ofp.OfpInstruction
	var actions ofp.OfpInstructionActions
	addTag.Type = uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS)
	addTag.Data = &ofp.OfpInstruction_Actions{
		Actions: &actions,
	}
	pushAction := flows.PushVlan(etherType)
	actions.Actions = append(actions.Actions, pushAction)
	var setField ofp.OfpOxmOfbField
	setField.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID
	setField.HasMask = false
	setField.Value = &ofp.OfpOxmOfbField_VlanVid{
		VlanVid: uint32(vlan&0x0fff + 0x1000),
	}
	setAction := flows.SetField(&setField)
	actions.Actions = append(actions.Actions, setAction)
	return &addTag
}

// NewPushVlanAction for push vlan action
func NewPushVlanAction(etherType uint32) *ofp.OfpAction {
	pushAction := flows.PushVlan(etherType)
	return pushAction
}

// NewSetVlanAction for set vlan action
func NewSetVlanAction(vlan uint16) *ofp.OfpAction {
	var setField ofp.OfpOxmOfbField
	setField.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID
	setField.HasMask = false
	and := (vlan & 0xfff)
	or := and + 0x1000
	v := uint32(vlan&0x0fff + 0x1000)
	logger.Infow(ctx, "Vlan Construction", log.Fields{"Vlan": vlan, "vlan&0x0fff": and, "OR": or, "final": v})
	setField.Value = &ofp.OfpOxmOfbField_VlanVid{
		VlanVid: uint32(vlan&0x0fff + 0x1000),
	}
	setAction := flows.SetField(&setField)
	return setAction
}

// NewSetPcpAction for set pcap action
func NewSetPcpAction(pbits PbitType) *ofp.OfpAction {
	var setField ofp.OfpOxmOfbField
	setField.Type = ofp.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP
	setField.HasMask = false
	setField.Value = &ofp.OfpOxmOfbField_VlanPcp{VlanPcp: uint32(pbits)}
	setAction := flows.SetField(&setField)
	return setAction
}

// NewOutputInstruction for output instructions
func NewOutputInstruction(port uint32) *ofp.OfpInstruction {
	var outport ofp.OfpInstruction
	var actions ofp.OfpInstructionActions
	outport.Type = uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS)
	outport.Data = &ofp.OfpInstruction_Actions{
		Actions: &actions,
	}
	action := flows.Output(port, 65535)
	actions.Actions = append(actions.Actions, action)
	return &outport
}

// NewOutputAction for output action
func NewOutputAction(port uint32) *ofp.OfpAction {
	return flows.Output(port, 65535)
}

// NewGroupOutputInstruction for group output instructions
func NewGroupOutputInstruction(group uint32) *ofp.OfpInstruction {
	var outgroup ofp.OfpInstruction
	var actions ofp.OfpInstructionActions
	outgroup.Type = uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS)
	outgroup.Data = &ofp.OfpInstruction_Actions{
		Actions: &actions,
	}
	action := flows.Group(group)
	actions.Actions = append(actions.Actions, action)
	return &outgroup
}

// NewGroupAction for group action
func NewGroupAction(group uint32) *ofp.OfpAction {
	return flows.Group(group)
}

// CreateMatchAndActions to create match list and action
func CreateMatchAndActions(f *VoltSubFlow) ([]*ofp.OfpOxmField, []*ofp.OfpInstruction) {
	logger.Debug(ctx, "Create Match and Action called")

	// Return values declared here
	var matchList []*ofp.OfpOxmField
	var instructions []*ofp.OfpInstruction

	// Construct the match rules
	// Add match in port
	if f.Match.InPort != 0 {
		entry := NewInportMatch(uint32(f.Match.InPort))
		matchList = append(matchList, entry)
	}

	// Add table metadata match
	if f.Match.TableMetadata != 0 {
		entry := NewTableMetadataMatch(uint64(f.Match.TableMetadata))
		matchList = append(matchList, entry)
	}

	// Add Src MAC address match
	if f.SrcMacMatch {
		entry := NewSrcMacAddrMatch(f.SrcMacAddr)
		matchList = append(matchList, entry)
	}

	// Add Src MAC address match
	if f.DstMacMatch {
		entry := NewDstMacAddrMatch(f.DstMacAddr)
		matchList = append(matchList, entry)
	}

	// Add VLAN tag match
	if f.MatchVlan != VlanNone {
		entry := NewVlanMatch(uint16(f.MatchVlan))
		matchList = append(matchList, entry)
	}

	if f.MatchPbits {
		entry := NewPcpMatch(f.Pbits)
		matchList = append(matchList, entry)
	}

	// Add EtherType match
	if f.L3Protocol != EtherTypeAny {
		entry := NewEthTypeMatch(uint16(f.L3Protocol))
		matchList = append(matchList, entry)
	}

	// Add the Src IPv4 addr match
	if f.SrcIpv4Match {
		entry := NewIpv4SrcMatch(f.SrcIpv4Addr)
		matchList = append(matchList, entry)
	}

	// Add the Dst IPv4 addr match
	if f.DstIpv4Match {
		entry := NewIpv4DstMatch(f.DstIpv4Addr)
		matchList = append(matchList, entry)
	}

	// Add IP protocol match
	if f.L4Protocol != IPProtocolIgnore {
		entry := NewIPProtoMatch(uint16(f.L4Protocol))
		matchList = append(matchList, entry)
	}

	// Add UDP Source port match
	if f.SrcPort != 0 {
		entry := NewUDPSrcMatch(uint16(f.SrcPort))
		matchList = append(matchList, entry)
	}

	// Add UDP Dest port match
	if f.DstPort != 0 {
		entry := NewUDPDstMatch(uint16(f.DstPort))
		matchList = append(matchList, entry)
	}

	// Construct the instructions
	// Add a GOTO table action
	if f.Output == OutputTypeGoToTable {
		instruction := NewGoToTableInstruction(f.GoToTableID)
		instructions = append(instructions, instruction)
	}

	// Add the meter instruction
	if f.MeterID != 0 {
		instruction := NewMeterIDInstruction(f.MeterID)
		instructions = append(instructions, instruction)
	}

	// Add the metadata instruction
	if f.Metadata != 0 {
		instruction := NewWriteMetadataInstruction(f.Metadata)
		instructions = append(instructions, instruction)
	}

	// The below are all apply actions. All of these could be combined into
	// a single instruction.
	{
		var instruction ofp.OfpInstruction
		var actions ofp.OfpInstructionActions
		instruction.Type = uint32(ofp.OfpInstructionType_OFPIT_APPLY_ACTIONS)
		instruction.Data = &ofp.OfpInstruction_Actions{
			Actions: &actions,
		}

		// Apply action of popping the VLAN
		if f.RemoveVlan != 0 {
			for i := 0; i < f.RemoveVlan; i++ {
				action := NewPopVlanAction()
				actions.Actions = append(actions.Actions, action)
			}
		}

		if f.SetVlan != VlanNone {
			action := NewSetVlanAction(uint16(f.SetVlan))
			actions.Actions = append(actions.Actions, action)
		}

		if f.Pcp != PbitNone {
			action := NewSetPcpAction(f.Pcp)
			actions.Actions = append(actions.Actions, action)
		}

		// Add the VLAN PUSH
		if len(f.PushVlan) != 0 {
			action := NewPushVlanAction(uint32(f.EtherType))
			actions.Actions = append(actions.Actions, action)
			for _, vlan := range f.PushVlan {
				action = NewSetVlanAction(uint16(vlan))
				actions.Actions = append(actions.Actions, action)
			}
		}

		if f.Action.Output == OutputTypeToController {
			action := NewOutputAction(0xfffffffd)
			actions.Actions = append(actions.Actions, action)
		} else if f.Action.Output == OutputTypeToNetwork {
			action := NewOutputAction(f.OutPort)
			actions.Actions = append(actions.Actions, action)
		} else if f.Action.Output == OutputTypeToGroup {
			action := NewGroupAction(f.OutPort)
			actions.Actions = append(actions.Actions, action)
		}
		instructions = append(instructions, &instruction)
	}

	return matchList, instructions
}

// CreateFlow to create flow
func CreateFlow(device string, command ofp.OfpFlowModCommand, matches []*ofp.OfpOxmField,
	instructions []*ofp.OfpInstruction, sf *VoltSubFlow) *ofp.FlowTableUpdate {
	flowUpdate := ofp.FlowTableUpdate{
		Id: device,
		FlowMod: &ofp.OfpFlowMod{
			Cookie:      sf.Cookie,
			CookieMask:  sf.CookieMask,
			TableId:     sf.TableID,
			Command:     command,
			IdleTimeout: uint32(0),
			HardTimeout: uint32(0),
			Priority:    sf.Priority,
			BufferId:    DefaultBufferID,
			OutPort:     DefaultOutPort,
			OutGroup:    DefaultOutGroup,
			Flags:       DefaultFlags,
			Match: &ofp.OfpMatch{
				Type:      ofp.OfpMatchType_OFPMT_OXM,
				OxmFields: matches,
			},

			Instructions: instructions,
		},
	}
	return &flowUpdate
}

// Processing logic for the VOLT flows. The VOLT flows are different from
// the normal openflows. Each VOLT flow may break into multiple flows.
// The order of processing:
// 1. If the flow has to match more than one VLAN tag, it is broken into
//    more than one flow.
// 2. When more than one flow is creatd, the higher layer processing is
//    broken into the second flow. The first flow includes only the
//    the processing of first VLAN tag.
// 3. The a sinle flow is created, the first flow has all the match criteria
//    and action.

// ProcessVoltFlow to process volt flow
func ProcessVoltFlow(device string, operation Command, subFlow map[uint64]*VoltSubFlow) []*ofp.FlowTableUpdate {
	var flows []*ofp.FlowTableUpdate
	var command ofp.OfpFlowModCommand
	if operation == CommandAdd {
		command = ofp.OfpFlowModCommand_OFPFC_ADD
	} else {
		command = ofp.OfpFlowModCommand_OFPFC_DELETE_STRICT
	}
	for _, sf := range subFlow {
		logger.Debugw(ctx, "Flow Construction for", log.Fields{"Flow": sf})
		match, instruction := CreateMatchAndActions(sf)
		flow := CreateFlow(device, command, match, instruction, sf)
		logger.Debugw(ctx, "Flow Constructed", log.Fields{"Flow": flow})
		flows = append(flows, flow)
	}
	return flows
}

func init() {
	// Setup this package so that it's log level can be modified at run time
	var err error
	logger, err = log.AddPackageWithDefaultParam()
	if err != nil {
		panic(err)
	}
}
