/*
 * Copyright 2019-present Ciena Corporation
 *
 * 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 model

import (
	"fmt"
	"github.com/jhump/protoreflect/dynamic"
)

type FlowFieldFlag uint64

const (

	// Define bit flags for flow fields to determine what is set and
	// what is not
	FLOW_FIELD_UNSUPPORTED_MATCH FlowFieldFlag = 1 << iota
	FLOW_FIELD_UNSUPPORTED_INSTRUCTION
	FLOW_FIELD_UNSUPPORTED_ACTION
	FLOW_FIELD_UNSUPPORTED_SET_FIELD
	FLOW_FIELD_ID
	FLOW_FIELD_TABLE_ID
	FLOW_FIELD_DURATION_SEC
	FLOW_FIELD_DURATION_NSEC
	FLOW_FIELD_IDLE_TIMEOUT
	FLOW_FIELD_HARD_TIMEOUT
	FLOW_FIELD_PACKET_COUNT
	FLOW_FIELD_BYTE_COUNT
	FLOW_FIELD_PRIORITY
	FLOW_FIELD_COOKIE
	FLOW_FIELD_IN_PORT
	FLOW_FIELD_ETH_TYPE
	FLOW_FIELD_VLAN_ID
	FLOW_FIELD_IP_PROTO
	FLOW_FIELD_UDP_SRC
	FLOW_FIELD_UDP_DST
	FLOW_FIELD_METADATA
	FLOW_FIELD_SET_VLAN_ID
	FLOW_FIELD_POP_VLAN
	FLOW_FIELD_PUSH_VLAN_ID
	FLOW_FIELD_OUTPUT
	FLOW_FIELD_GOTO_TABLE
	FLOW_FIELD_WRITE_METADATA
	FLOW_FIELD_CLEAR_ACTIONS
	FLOW_FIELD_METER
	FLOW_FIELD_TUNNEL_ID
	FLOW_FIELD_VLAN_PCP

	FLOW_FIELD_HEADER = FLOW_FIELD_ID | FLOW_FIELD_TABLE_ID |
		FLOW_FIELD_PRIORITY | FLOW_FIELD_COOKIE

	FLOW_FIELD_STATS = FLOW_FIELD_DURATION_SEC | FLOW_FIELD_DURATION_NSEC |
		FLOW_FIELD_IDLE_TIMEOUT | FLOW_FIELD_HARD_TIMEOUT |
		FLOW_FIELD_PACKET_COUNT | FLOW_FIELD_BYTE_COUNT
)

var (
	// Provide an array of all flags that can be used for iteration
	AllFlowFieldFlags = []FlowFieldFlag{
		FLOW_FIELD_UNSUPPORTED_MATCH,
		FLOW_FIELD_UNSUPPORTED_INSTRUCTION,
		FLOW_FIELD_UNSUPPORTED_ACTION,
		FLOW_FIELD_UNSUPPORTED_SET_FIELD,
		FLOW_FIELD_ID,
		FLOW_FIELD_TABLE_ID,
		FLOW_FIELD_DURATION_SEC,
		FLOW_FIELD_DURATION_NSEC,
		FLOW_FIELD_IDLE_TIMEOUT,
		FLOW_FIELD_HARD_TIMEOUT,
		FLOW_FIELD_PACKET_COUNT,
		FLOW_FIELD_BYTE_COUNT,
		FLOW_FIELD_PRIORITY,
		FLOW_FIELD_COOKIE,
		FLOW_FIELD_IN_PORT,
		FLOW_FIELD_ETH_TYPE,
		FLOW_FIELD_VLAN_ID,
		FLOW_FIELD_IP_PROTO,
		FLOW_FIELD_UDP_SRC,
		FLOW_FIELD_UDP_DST,
		FLOW_FIELD_METADATA,
		FLOW_FIELD_SET_VLAN_ID,
		FLOW_FIELD_POP_VLAN,
		FLOW_FIELD_PUSH_VLAN_ID,
		FLOW_FIELD_OUTPUT,
		FLOW_FIELD_GOTO_TABLE,
		FLOW_FIELD_WRITE_METADATA,
		FLOW_FIELD_CLEAR_ACTIONS,
		FLOW_FIELD_METER,
		FLOW_FIELD_TUNNEL_ID,
		FLOW_FIELD_VLAN_PCP,
	}
)

func (f *FlowFieldFlag) Count() int {
	var count int
	var bit uint64 = 1
	var asUint64 = uint64(*f)
	for i := 0; i < 64; i += 1 {
		if asUint64&bit > 0 {
			count += 1
		}
		bit <<= 1
	}
	return count
}
func (f *FlowFieldFlag) IsSet(flag FlowFieldFlag) bool {
	return *f&flag > 0
}

func (f *FlowFieldFlag) Set(flag FlowFieldFlag) {
	*f |= flag
}

func (f *FlowFieldFlag) Clear(flag FlowFieldFlag) {
	var mask = ^(flag)
	*f &= mask
}

func (f *FlowFieldFlag) Reset() {
	*f = 0
}

func (f FlowFieldFlag) String() string {
	switch f {
	case FLOW_FIELD_UNSUPPORTED_MATCH:
		return "UnsupportedMatch"
	case FLOW_FIELD_UNSUPPORTED_INSTRUCTION:
		return "UnsupportedInstruction"
	case FLOW_FIELD_UNSUPPORTED_ACTION:
		return "UnsupportedAction"
	case FLOW_FIELD_UNSUPPORTED_SET_FIELD:
		return "UnsupportedSetField"
	case FLOW_FIELD_ID:
		return "Id"
	case FLOW_FIELD_TABLE_ID:
		return "TableId"
	case FLOW_FIELD_DURATION_SEC:
		return "DurationSec"
	case FLOW_FIELD_DURATION_NSEC:
		return "DurationNsec"
	case FLOW_FIELD_IDLE_TIMEOUT:
		return "IdleTimeout"
	case FLOW_FIELD_HARD_TIMEOUT:
		return "HardTimeout"
	case FLOW_FIELD_PACKET_COUNT:
		return "PacketCount"
	case FLOW_FIELD_BYTE_COUNT:
		return "ByteCount"
	case FLOW_FIELD_PRIORITY:
		return "Priority"
	case FLOW_FIELD_COOKIE:
		return "Cookie"
	case FLOW_FIELD_IN_PORT:
		return "InPort"
	case FLOW_FIELD_ETH_TYPE:
		return "EthType"
	case FLOW_FIELD_VLAN_ID:
		return "VlanId"
	case FLOW_FIELD_IP_PROTO:
		return "IpProto"
	case FLOW_FIELD_UDP_SRC:
		return "UdpSrc"
	case FLOW_FIELD_UDP_DST:
		return "UdpDst"
	case FLOW_FIELD_METADATA:
		return "Metadata"
	case FLOW_FIELD_SET_VLAN_ID:
		return "SetVlanId"
	case FLOW_FIELD_POP_VLAN:
		return "PopVlan"
	case FLOW_FIELD_PUSH_VLAN_ID:
		return "PushVlanId"
	case FLOW_FIELD_OUTPUT:
		return "Output"
	case FLOW_FIELD_GOTO_TABLE:
		return "GotoTable"
	case FLOW_FIELD_WRITE_METADATA:
		return "WriteMetadata"
	case FLOW_FIELD_CLEAR_ACTIONS:
		return "ClearActions"
	case FLOW_FIELD_METER:
		return "MeterId"
	case FLOW_FIELD_TUNNEL_ID:
		return "TunnelId"
	case FLOW_FIELD_VLAN_PCP:
		return "VlanPcp"
	default:
		return "UnknownFieldFlag"
	}
}

/*
 * This is a partial list of OF match/action values. This list will be
 * expanded as new fields are needed within VOLTHA
 *
 * Strings are used in the output structure so that on output the table
 * can be "sparsely" populated with "empty" cells as opposed to 0 (zeros)
 * all over the place.
 */
type Flow struct {
	Id                     string `json:"id"`
	TableId                uint32 `json:"tableid"`
	DurationSec            uint32 `json:"durationsec"`
	DurationNsec           uint32 `json:"durationnsec"`
	IdleTimeout            uint32 `json:"idletimeout"`
	HardTimeout            uint32 `json:"hardtimeout"`
	PacketCount            uint64 `json:"packetcount"`
	ByteCount              uint64 `json:"bytecount"`
	Priority               uint32 `json:"priority"`
	Cookie                 string `json:"cookie"`
	UnsupportedMatch       string `json:"unsupportedmatch,omitempty"`
	InPort                 string `json:"inport,omitempty"`
	EthType                string `json:"ethtype,omitempty"`
	VlanId                 string `json:"vlanid,omitempty"`
	IpProto                string `json:"ipproto,omitempty"`
	UdpSrc                 string `json:"udpsrc,omitempty"`
	UdpDst                 string `json:"dstsrc,omitempty"`
	Metadata               string `json:"metadata,omitempty"`
	UnsupportedInstruction string `json:"unsupportedinstruction,omitempty"`
	UnsupportedAction      string `json:"unsupportedaction,omitempty"`
	UnsupportedSetField    string `json:"unsupportedsetfield,omitempty"`
	SetVlanId              string `json:"setvlanid,omitempty"`
	PopVlan                string `json:"popvlan,omitempty"`
	PushVlanId             string `json:"pushvlanid,omitempty"`
	Output                 string `json:"output,omitempty"`
	GotoTable              string `json:"gototable,omitempty"`
	WriteMetadata          string `json:"writemetadata,omitempty"`
	ClearActions           string `json:"clear,omitempty"`
	MeterId                string `json:"meter,omitempty"`
	TunnelId               string `json:"tunnelid,omitempty"`
	VlanPcp                string `json:"vlanpcp,omitempty"`

	populated FlowFieldFlag
}

func (f *Flow) Count() int {
	return f.populated.Count()
}

func (f *Flow) IsSet(flag FlowFieldFlag) bool {
	return f.populated.IsSet(flag)
}

func (f *Flow) Set(flag FlowFieldFlag) {
	f.populated.Set(flag)
}

func (f *Flow) Clear(flag FlowFieldFlag) {
	f.populated.Clear(flag)
}

func (f *Flow) Reset() {
	f.populated.Reset()
}

func (f *Flow) Populated() FlowFieldFlag {
	return f.populated
}

func toVlanId(vid uint32) string {
	if vid == 0 {
		return "untagged"
	} else if vid&0x1000 > 0 {
		return fmt.Sprintf("%d", vid-4096)
	}
	return fmt.Sprintf("%d", vid)
}

func appendInt32(base string, val int32) string {
	if len(base) > 0 {
		return fmt.Sprintf("%s,%d", base, val)
	}
	return fmt.Sprintf("%d", val)
}

func appendUint32(base string, val uint32) string {
	if len(base) > 0 {
		return fmt.Sprintf("%s,%d", base, val)
	}
	return fmt.Sprintf("%d", val)
}

func (f *Flow) PopulateFrom(val *dynamic.Message) {

	f.Reset()
	f.Id = fmt.Sprintf("%016x", val.GetFieldByName("id").(uint64))
	f.TableId = val.GetFieldByName("table_id").(uint32)
	f.Priority = val.GetFieldByName("priority").(uint32)
	// mask the lower 8 for the cookie, why?
	cookie := val.GetFieldByName("cookie").(uint64)
	if cookie == 0 {
		f.Cookie = "0"
	} else {
		f.Cookie = fmt.Sprintf("~%08x", val.GetFieldByName("cookie").(uint64)&0xffffffff)
	}
	f.DurationSec = val.GetFieldByName("duration_sec").(uint32)
	f.DurationNsec = val.GetFieldByName("duration_nsec").(uint32)
	f.IdleTimeout = val.GetFieldByName("idle_timeout").(uint32)
	f.HardTimeout = val.GetFieldByName("hard_timeout").(uint32)
	f.PacketCount = val.GetFieldByName("packet_count").(uint64)
	f.ByteCount = val.GetFieldByName("byte_count").(uint64)
	f.Set(FLOW_FIELD_HEADER | FLOW_FIELD_STATS)

	match := val.GetFieldByName("match").(*dynamic.Message)
	fields := match.GetFieldByName("oxm_fields")
	for _, ifield := range fields.([]interface{}) {
		field := ifield.(*dynamic.Message)

		// Only support OFPXMC_OPENFLOW_BASIC (0x8000)
		if field.GetFieldByName("oxm_class").(int32) != 0x8000 {
			continue
		}

		basic := field.GetFieldByName("ofb_field").(*dynamic.Message)
		switch basic.GetFieldByName("type").(int32) {
		case 0: // IN_PORT
			f.Set(FLOW_FIELD_IN_PORT)
			f.InPort = fmt.Sprintf("%d", basic.GetFieldByName("port").(uint32))
		case 2: // METADATA
			f.Set(FLOW_FIELD_METADATA)
			f.Metadata = fmt.Sprintf("0x%016x", basic.GetFieldByName("table_metadata").(uint64))
		case 5: // ETH_TYPE
			f.Set(FLOW_FIELD_ETH_TYPE)
			f.EthType = fmt.Sprintf("0x%04x", basic.GetFieldByName("eth_type").(uint32))
		case 6: // VLAN_ID
			f.Set(FLOW_FIELD_VLAN_ID)
			f.VlanId = toVlanId(basic.GetFieldByName("vlan_vid").(uint32))
		case 7: // VLAN_PCP
			f.Set(FLOW_FIELD_VLAN_PCP)
			f.VlanPcp = fmt.Sprintf("%d", basic.GetFieldByName("vlan_pcp").(uint32))
		case 10: // IP_PROTO
			f.Set(FLOW_FIELD_IP_PROTO)
			f.IpProto = fmt.Sprintf("%d", basic.GetFieldByName("ip_proto").(uint32))
		case 15: // UDP_SRC
			f.Set(FLOW_FIELD_UDP_SRC)
			f.UdpSrc = fmt.Sprintf("%d", basic.GetFieldByName("udp_src").(uint32))
		case 16: // UDP_DST
			f.Set(FLOW_FIELD_UDP_DST)
			f.UdpDst = fmt.Sprintf("%d", basic.GetFieldByName("udp_dst").(uint32))
		case 38: // TUNNEL_ID
			f.Set(FLOW_FIELD_TUNNEL_ID)
			f.TunnelId = fmt.Sprintf("%d", basic.GetFieldByName("tunnel_id").(uint64))
		default:
			/*
			 * For unsupported match types put them into an
			 * "Unsupported field so the table/json still
			 * outputs relatively correctly as opposed to
			 * having log messages.
			 */
			f.Set(FLOW_FIELD_UNSUPPORTED_MATCH)
			f.UnsupportedMatch = appendInt32(f.UnsupportedMatch, basic.GetFieldByName("type").(int32))
		}
	}
	for _, instruction := range val.GetFieldByName("instructions").([]interface{}) {
		inst := instruction.(*dynamic.Message)
		switch inst.GetFieldByName("type").(uint32) {
		case 1: // GOTO_TABLE
			f.Set(FLOW_FIELD_GOTO_TABLE)
			goto_table := inst.GetFieldByName("goto_table").(*dynamic.Message)
			f.GotoTable = fmt.Sprintf("%d", goto_table.GetFieldByName("table_id").(uint32))
		case 2: // WRITE_METADATA
			f.Set(FLOW_FIELD_WRITE_METADATA)
			meta := inst.GetFieldByName("write_metadata").(*dynamic.Message)
			val := meta.GetFieldByName("metadata").(uint64)
			mask := meta.GetFieldByName("metadata_mask").(uint64)
			if mask != 0 {
				f.WriteMetadata = fmt.Sprintf("0x%016x/0x%016x", val, mask)
			} else {
				f.WriteMetadata = fmt.Sprintf("0x%016x", val)
			}
		case 4: // APPLY_ACTIONS
			actions := inst.GetFieldByName("actions").(*dynamic.Message)
			for _, action := range actions.GetFieldByName("actions").([]interface{}) {
				a := action.(*dynamic.Message)
				switch a.GetFieldByName("type").(int32) {
				case 0: // OUTPUT
					f.Set(FLOW_FIELD_OUTPUT)
					output := a.GetFieldByName("output").(*dynamic.Message)
					out := output.GetFieldByName("port").(uint32)
					switch out & 0x7fffffff {
					case 0:
						f.Output = "INVALID"
					case 0x7ffffff8:
						f.Output = "IN_PORT"
					case 0x7ffffff9:
						f.Output = "TABLE"
					case 0x7ffffffa:
						f.Output = "NORMAL"
					case 0x7ffffffb:
						f.Output = "FLOOD"
					case 0x7ffffffc:
						f.Output = "ALL"
					case 0x7ffffffd:
						f.Output = "CONTROLLER"
					case 0x7ffffffe:
						f.Output = "LOCAL"
					case 0x7fffffff:
						f.Output = "ANY"
					default:
						f.Output = fmt.Sprintf("%d", output.GetFieldByName("port").(uint32))
					}
				case 17: // PUSH_VLAN
					f.Set(FLOW_FIELD_PUSH_VLAN_ID)
					push := a.GetFieldByName("push").(*dynamic.Message)
					f.PushVlanId = fmt.Sprintf("0x%x", push.GetFieldByName("ethertype").(uint32))
				case 18: // POP_VLAN
					f.Set(FLOW_FIELD_POP_VLAN)
					f.PopVlan = "yes"
				case 25: // SET_FIELD
					set := a.GetFieldByName("set_field").(*dynamic.Message).GetFieldByName("field").(*dynamic.Message)

					// Only support OFPXMC_OPENFLOW_BASIC (0x8000)
					if set.GetFieldByName("oxm_class").(int32) != 0x8000 {
						continue
					}
					basic := set.GetFieldByName("ofb_field").(*dynamic.Message)

					switch basic.GetFieldByName("type").(int32) {
					case 6: // VLAN_ID
						f.Set(FLOW_FIELD_SET_VLAN_ID)
						f.SetVlanId = toVlanId(basic.GetFieldByName("vlan_vid").(uint32))
					default: // Unsupported
						/*
						 * For unsupported match types put them into an
						 * "Unsupported field so the table/json still
						 * outputs relatively correctly as opposed to
						 * having log messages.
						 */
						f.Set(FLOW_FIELD_UNSUPPORTED_SET_FIELD)
						f.UnsupportedSetField = appendInt32(f.UnsupportedSetField,
							basic.GetFieldByName("type").(int32))
					}
				default: // Unsupported
					/*
					 * For unsupported match types put them into an
					 * "Unsupported field so the table/json still
					 * outputs relatively correctly as opposed to
					 * having log messages.
					 */
					f.Set(FLOW_FIELD_UNSUPPORTED_ACTION)
					f.UnsupportedAction = appendInt32(f.UnsupportedAction,
						a.GetFieldByName("type").(int32))
				}
			}
		case 5: // CLEAR_ACTIONS
			// Following current CLI, just assigning empty list
			f.Set(FLOW_FIELD_CLEAR_ACTIONS)
			f.ClearActions = "[]"
		case 6: // METER
			meter := inst.GetFieldByName("meter").(*dynamic.Message)
			f.Set(FLOW_FIELD_METER)
			f.MeterId = fmt.Sprintf("%d", meter.GetFieldByName("meter_id").(uint32))
		default: // Unsupported
			/*
			 * For unsupported match types put them into an
			 * "Unsupported field so the table/json still
			 * outputs relatively correctly as opposed to
			 * having log messages.
			 */
			f.Set(FLOW_FIELD_UNSUPPORTED_INSTRUCTION)
			f.UnsupportedInstruction = appendUint32(f.UnsupportedInstruction,
				inst.GetFieldByName("type").(uint32))
		}
	}
}
