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

	"voltha-go-controller/log"

	"github.com/opencord/voltha-lib-go/v7/pkg/flows"
	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 {
	SrcMacAddr    net.HardwareAddr
	SrcMacMask    net.HardwareAddr
	DstMacAddr    net.HardwareAddr
	DstMacMask    net.HardwareAddr
	SrcIpv4Addr   net.IP
	DstIpv4Addr   net.IP
	TableMetadata uint64
	InPort        uint32
	MatchVlan     VlanType
	Pbits         PbitType
	L3Protocol    EtherType
	SrcPort       uint16
	DstPort       uint16
	L4Protocol    IPProtocol
	DstIpv4Match  bool
	SrcIpv4Match  bool
	SrcMacMatch   bool
	DstMacMatch   bool
	MatchPbits    bool
}

// 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 {
	PushVlan    []VlanType
	Metadata    uint64
	RemoveVlan  int
	OutPort     uint32
	GoToTableID uint32
	MeterID     uint32
	EtherType   layers.EthernetType
	SetVlan     VlanType
	Pcp         PbitType
	Output      OutputType
}

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 {
	ErrorReason string
	Match
	Action
	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
	FlowCount uint32
}

// 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 {
	SubFlows map[uint64]*VoltSubFlow
	// PortName and PortID to be used for validation of port before flow pushing
	PortName      string
	PortID        uint32
	Command       Command
	ForceAction   bool
	MigrateCookie bool
}

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.Debugw(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)
	}
}
