#
# Copyright 2018 the original author or authors.
#
# 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.
#

from pyvoltha.protos.device_pb2 import Port
import pyvoltha.protos.device_pb2 as dev_pb2

#######################################################################
#
#  This is a copy of the OpenOLT file of a similar name and is used
#  when running in non-xPON (OpenOLT/SEBA) mode.  We need to closely
#  watch for changes in the OpenOLT and eventually work together to
#  have a better way to do things (and more ONUs than 112)
#
#  TODO: These duplicate some methods in the OLT Handler.  Clean up
#        and use a separate file and include it into OLT Handler object
#        as something it derives from.
#
#######################################################################
"""
Encoding of identifiers
=======================

Alloc ID

    Uniquely identifies a T-CONT
    Ranges from 1024..16383 per ITU Standard
    For Adtran, 1024..1919
    Unique per PON interface

     9   8 7        0
    +-----+----------+
    | idx |  onu_id  | + (Min Alloc ID)
    +-----+----------+

    onu id = 8 bit
    Alloc index = 2 bits (max 4 TCONTs/ONU)

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


PON OLT (OF) port number

    OpenFlow port number corresponding to PON OLT ports

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

"""

MIN_TCONT_ALLOC_ID = 1024                   # 1024..16383
MAX_TCONT_ALLOC_ID = 16383

MIN_GEM_PORT_ID = 2176                      # 2176..4222
MAX_GEM_PORT_ID = MIN_GEM_PORT_ID + 2046

MAX_ONUS_PER_PON = 128
MAX_TCONTS_PER_ONU = 4
MAX_GEM_PORTS_PER_ONU = 16          # Hardware can handle more


class adtran_platform(object):
    def __init__(self):
        pass

    def mk_uni_port_num(self, intf_id, onu_id, uni_id=0):
        return intf_id << 11 | onu_id << 4 | uni_id

    def uni_id_from_uni_port(self, uni_port):
        return uni_port & 0xF


def mk_uni_port_num(intf_id, onu_id, uni_id=0):
    """
    Create a unique virtual UNI port number based up on PON and ONU ID
    :param intf_id:
    :param onu_id: (int) ONU ID (0..max)
    :return: (int) UNI Port number
    """
    return intf_id << 11 | onu_id << 4 | uni_id


def uni_id_from_uni_port(uni_port):
    return uni_port & 0xF


def intf_id_from_uni_port_num(port_num):
    """
    Extract the PON device port number from a virtual UNI Port number

    :param port_num: (int) virtual UNI / vENET port number on OLT PON
    :return: (int) PON Port number (note, this is not the PON ID)
    """
    return (port_num >> 11) & 0xF


def mk_alloc_id(_, onu_id, idx=0):
    """
    Allocate a TCONT Alloc-ID.    This is only called by the OLT

    :param _: (int)         PON ID (not used)
    :param onu_id: (int)    ONU ID (0..MAX_ONUS_PER_PON-1)
    :param idx: (int)       TCONT Index (0..7)
    """
    assert 0 <= onu_id < MAX_ONUS_PER_PON, 'Invalid ONU ID. Expect 0..{}'.format(MAX_ONUS_PER_PON-1)
    assert 0 <= idx <= MAX_TCONTS_PER_ONU, 'Invalid TCONT instance. Expect 0..{}'.format(MAX_TCONTS_PER_ONU)
    alloc_id = MIN_TCONT_ALLOC_ID + (idx << 8) + onu_id
    return alloc_id


def intf_id_from_nni_port_num(port_num):
    # OpenOLT starts at 128.  We start at 1 (one-to-one mapping)
    # return port_num - 128
    return port_num


def intf_id_to_intf_type(intf_id):
    # if (2 << 28 ^ intf_id) < 16:
    #     return Port.PON_OLT
    # elif  128 <= intf_id <= 132:
    #     return Port.ETHERNET_NNI
    if 5 <= intf_id <= 20:
        return Port.PON_OLT
    elif 1 <= intf_id <= 4:
        return Port.ETHERNET_NNI
    else:
        raise Exception('Invalid intf_id value')


def is_upstream(in_port, out_port):
    # FIXME
    # if out_port in [128, 129, 130, 131, 0xfffd, 0xfffffffd]:
    # Not sure what fffd and the other is
    return out_port in [1, 2, 3, 4, 0xfffd, 0xfffffffd]


def is_downstream(in_port, out_port):
    return not is_upstream(in_port, out_port)
