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

// 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)
	}
}
