/*
 * Copyright 2018-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 adaptercore
import (voltha "github.com/opencord/voltha-protos/go/voltha");

/*=====================================================================

Flow id

    Identifies a flow within a single OLT
    Flow Id is unique per OLT
    Multiple GEM ports can map to same flow id

     13    11              4      0
    +--------+--------------+------+
    | pon id |    onu id    | Flow |
    |        |              | idx  |
    +--------+--------------+------+

    14 bits = 16384 flows (per OLT).

    pon id = 4 bits = 16 PON ports
    onu id = 7 bits = 128 ONUss per PON port
    Flow index = 3 bits = 4 bi-directional flows per ONU
                        = 8 uni-directional flows per ONU


Logical (OF) UNI port number

    OpenFlow port number corresponding to PON UNI

     15       11              4      0
    +--+--------+--------------+------+
    |0 | pon id |    onu id    |   0  |
    +--+--------+--------------+------+

    pon id = 4 bits = 16 PON ports
    onu id = 7 bits = 128 ONUs per PON port

Logical (OF) NNI port number

    OpenFlow port number corresponding to PON UNI

     16                             0
    +--+----------------------------+
    |1 |                    intf_id |
    +--+----------------------------+

    No overlap with UNI port number space


PON OLT (OF) port number

    OpenFlow port number corresponding to PON OLT ports

     31    28                                 0
    +--------+------------------------~~~------+
    |  0x2   |          pon intf id            |
    +--------+------------------------~~~------+
*/

var MAX_ONUS_PER_PON = 32;
var MIN_UPSTREAM_PORT_ID = 0xfffd;
var MAX_UPSTREAM_PORT_ID = 0xfffffffd;

func MkUniPortNum(intfId uint32, onuId uint32, uniId uint32) uint32 {
/* TODO: Add checks */
        return ((intfId << 11) | (onuId << 4) | uniId)
}

func MkFlowId(intfId uint32, onuId uint32, idx uint32) uint32 {
	return (((intfId << 9) | (onuId << 4)) | idx)
}

func OnuIdFromPortNum(portNum uint32) uint32 {
	return ((portNum >> 4) & 127)
}

func IntfIdFromUniPortNum(portNum uint32) uint32 {
	return ((portNum >> 11) & 15)
}

func UniIdFromPortNum(portNum uint32) uint32 {
        return ((portNum) & 0xF)
}



func IntfIdFromPonPortNo(portNo uint32) uint32 {
	return (portNo & 15)
}

func IntfIdToPortNo(intfId uint32, intfType voltha.Port_PortType) uint32 {
	if (( intfType ) == voltha.Port_ETHERNET_NNI) {
		return ((1 << 16) | intfId)
	} else {
		if (( intfType ) == voltha.Port_PON_OLT) {
			return ((2 << 28) | intfId)
		} else {
			return 0
		}
	}
}

func IntfIdFromNniPortNum(portNum uint32) uint32 {
	return (portNum & 0xFFFF)
}

func IntfIdToPortTypeName(intfId uint32) voltha.Port_PortType {
	if (( ((2 << 28) ^ intfId) ) < 16) {
		return voltha.Port_PON_OLT
	} else {
		if ( (intfId & (1 << 16)) ) == ( (1 << 16) ) {
			return voltha.Port_ETHERNET_NNI
		} else {
			return voltha.Port_UNKNOWN
		}
	}
}

func PortTypeNameByPortIndex(portIndex int32) string {
	return voltha.Port_PortType_name[portIndex]
}

func ExtractAccessFromFlow(inPort uint32, outPort uint32) (uint32, uint32, uint32, uint32) {
	if (IsUpstream(outPort)) {
                return inPort, IntfIdFromUniPortNum(inPort), OnuIdFromPortNum(inPort), UniIdFromPortNum(inPort)
	} else {
                return outPort, IntfIdFromUniPortNum(outPort), OnuIdFromPortNum(outPort), UniIdFromPortNum(outPort)
	}
}

func IsUpstream(outPort uint32) bool {
	if ((outPort >= uint32(MIN_UPSTREAM_PORT_ID)) && (outPort <= uint32(MAX_UPSTREAM_PORT_ID))) {
		return true
	}
	if ( (outPort & (1 << 16)) ) == ( (1 << 16) ) {
		return true
	}
	return false
}
