# CCopyright 2017-present Adtran, Inc.
#
# 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 twisted.internet.defer import inlineCallbacks, returnValue
import xmltodict
import structlog
from pyvoltha.protos.openflow_13_pb2 import OFPPF_1GB_FD, OFPPF_10GB_FD, OFPPF_40GB_FD, OFPPF_100GB_FD
from pyvoltha.protos.openflow_13_pb2 import OFPPF_FIBER, OFPPF_COPPER
from pyvoltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPC_PORT_DOWN, OFPPS_LINK_DOWN, OFPPF_OTHER
from pyvoltha.protos.common_pb2 import OperStatus, AdminState

log = structlog.get_logger()

_ietf_interfaces_config_rpc = """
    <filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
      <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
        <interface/>
      </interfaces>
    </filter>
"""

_ietf_interfaces_state_rpc = """
    <filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
      <interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
        <interface>
          <name/>
          <type/>
          <admin-status/>
          <oper-status/>
          <last-change/>
          <phys-address/>
          <speed/>
        </interface>
      </interfaces-state>
    </filter>
"""

_allowed_with_default_types = ['report-all', 'report-all-tagged', 'trim', 'explicit']

# TODO: Centralize the item below as a function in a core util module


def _with_defaults(default_type=None):
    if default_type is None:
        return ""

    assert(default_type in _allowed_with_default_types)
    return """
    <with-defaults xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults">
        {}</with-defaults>""".format(default_type)


class IetfInterfacesConfig(object):
    def __init__(self, session):
        self._session = session

    @inlineCallbacks
    def get_config(self, source='running', with_defaults=None):

        filter = _ietf_interfaces_config_rpc + _with_defaults(with_defaults)

        request = self._session.get(source, filter=filter)
        rpc_reply = yield request
        returnValue(rpc_reply)

    def get_interfaces(self, rpc_reply, interface_type=None):
        """
        Get the physical entities of a particular type
        :param rpc_reply: Reply from previous get or request
        :param interface_type: (String or List) The type of interface (case-insensitive)
        :return: list) of OrderDict interface entries
        """
        result_dict = xmltodict.parse(rpc_reply.data_xml)

        entries = result_dict['data']['interfaces']

        if interface_type is None:
            return entries

        # for entry in entries:
        #     import pprint
        #     log.info(pprint.PrettyPrinter(indent=2).pformat(entry))

        def _matches(entry, value):
            if 'type' in entry and '#text' in entry['type']:
                text_val = entry['type']['#text'].lower()
                if isinstance(value, list):
                    return any(v.lower() in text_val for v in value)
                return value.lower() in text_val
            return False

        return [entry for entry in entries if _matches(entry, interface_type)]


class IetfInterfacesState(object):
    def __init__(self, session):
        self._session = session

    @inlineCallbacks
    def get_state(self):
        try:
            request = self._session.get(_ietf_interfaces_state_rpc)
            rpc_reply = yield request
            returnValue(rpc_reply)

        except Exception as e:
            log.exception('get_state', e=e)
            raise

    @staticmethod
    def get_interfaces(self, rpc_reply, key='type', key_value=None):
        """
        Get the physical entities of a particular type
        :param key_value: (String or List) The type of interface (case-insensitive)
        :return: list) of OrderDict interface entries
        """
        result_dict = xmltodict.parse(rpc_reply.data_xml)
        entries = result_dict['data']['interfaces-state']['interface']

        if key_value is None:
            return entries

        for entry in entries:
            import pprint
            log.info(pprint.PrettyPrinter(indent=2).pformat(entry))

        def _matches(entry, key, value):
            if key in entry and '#text' in entry[key]:
                text_val = entry[key]['#text'].lower()
                if isinstance(value, list):
                    return any(v.lower() in text_val for v in value)
                return value.lower() in text_val
            return False

        return [entry for entry in entries if _matches(entry, key, key_value)]

    @staticmethod
    def _get_admin_state(entry):
        state_map = {
            'up': AdminState.ENABLED,
            'down': AdminState.DISABLED,
            'testing': AdminState.DISABLED
        }
        return state_map.get(entry.get('admin-status', 'down'),
                             AdminState.UNKNOWN)

    @staticmethod
    def _get_oper_status(entry):
        state_map = {
            'up': OperStatus.ACTIVE,
            'down': OperStatus.FAILED,
            'testing': OperStatus.TESTING,
            'unknown': OperStatus.UNKNOWN,
            'dormant': OperStatus.DISCOVERED,
            'not-present': OperStatus.UNKNOWN,
            'lower-layer-down': OperStatus.FAILED
        }
        return state_map.get(entry.get('oper-status', 'down'),
                             OperStatus.UNKNOWN)

    @staticmethod
    def _get_mac_addr(entry):
        mac_addr = entry.get('phys-address', None)
        if mac_addr is None:
            import random
            # TODO: Get with qumram team about phys addr
            mac_addr = '08:00:{}{}:{}{}:{}{}:00'.format(random.randint(0, 9),
                                                        random.randint(0, 9),
                                                        random.randint(0, 9),
                                                        random.randint(0, 9),
                                                        random.randint(0, 9),
                                                        random.randint(0, 9))
        return mac_addr

    @staticmethod
    def _get_speed_value(entry):
        speed = entry.get('speed') or IetfInterfacesState._get_speed_via_name(entry.get('name'))
        if isinstance(speed, str):
            return long(speed)
        return speed

    @staticmethod
    def _get_speed_via_name(name):
        speed_map = {
            'terabit':         1000000000000,
            'hundred-gigabit':  100000000000,
            'fourty-gigabit':    40000000000,
            'ten-gigabit':       10000000000,
            'gigabit':            1000000000,
        }
        for n,v in speed_map.iteritems():
            if n in name.lower():
                return v
        return 0

    @staticmethod
    def _get_of_state(entry):
        # If port up and ready: OFPPS_LIVE
        # If port config bit is down: OFPPC_PORT_DOWN
        # If port state bit is down: OFPPS_LINK_DOWN
        # if IetfInterfacesState._get_admin_state(entry) == AdminState.ENABLED:
        #     return OFPPS_LIVE \
        #         if IetfInterfacesState._get_oper_status(entry) == OperStatus.ACTIVE \
        #         else OFPPS_LINK_DOWN
        #
        # return OFPPC_PORT_DOWN
        # TODO: Update of openflow port state is not supported, so always say we are alive
        return OFPPS_LIVE

    @staticmethod
    def _get_of_capabilities(entry):
        # The capabilities field is a bitmap that uses a combination of the following flags :
        # Capabilities supported by the datapath
        # enum ofp_capabilities {
        #    OFPC_FLOW_STATS = 1 << 0,   /* Flow statistics. */
        #    OFPC_TABLE_STATS = 1 << 1,  /* Table statistics. */
        #    OFPC_PORT_STATS = 1 << 2,   /* Port statistics. */
        #    OFPC_GROUP_STATS = 1 << 3,  /* Group statistics. */
        #    OFPC_IP_REASM = 1 << 5,     /* Can reassemble IP fragments. */
        #    OFPC_QUEUE_STATS = 1 << 6,  /* Queue statistics. */
        #    OFPC_PORT_BLOCKED = 1 << 8, /* Switch will block looping ports. */
        #    OFPC_BUNDLES = 1 << 9,      /* Switch supports bundles. */
        #    OFPC_FLOW_MONITORING = 1 << 10, /* Switch supports flow monitoring. */
        # }
        # enum ofp_port_features {
        #     OFPPF_10MB_HD = 1 << 0, /* 10 Mb half-duplex rate support. */
        #     OFPPF_10MB_FD = 1 << 1, /* 10 Mb full-duplex rate support. */
        #     OFPPF_100MB_HD = 1 << 2, /* 100 Mb half-duplex rate support. */
        #     OFPPF_100MB_FD = 1 << 3, /* 100 Mb full-duplex rate support. */
        #     OFPPF_1GB_HD = 1 << 4, /* 1 Gb half-duplex rate support. */
        #     OFPPF_1GB_FD = 1 << 5, /* 1 Gb full-duplex rate support. */
        #     OFPPF_10GB_FD = 1 << 6, /* 10 Gb full-duplex rate support. */
        #     OFPPF_40GB_FD = 1 << 7, /* 40 Gb full-duplex rate support. */
        #     OFPPF_100GB_FD = 1 << 8, /* 100 Gb full-duplex rate support. */
        #     OFPPF_1TB_FD = 1 << 9, /* 1 Tb full-duplex rate support. */
        #     OFPPF_OTHER = 1 << 10, /* Other rate, not in the list. */
        #     OFPPF_COPPER = 1 << 11, /* Copper medium. */
        #     OFPPF_FIBER = 1 << 12, /* Fiber medium. */
        #     OFPPF_AUTONEG = 1 << 13, /* Auto-negotiation. */
        #     OFPPF_PAUSE = 1 << 14, /* Pause. */
        #     OFPPF_PAUSE_ASYM = 1 << 15 /* Asymmetric pause. */
        # }
        # TODO: Look into adtran-physical-entities and decode xSFP type any other settings
        return IetfInterfacesState._get_of_speed(entry) | OFPPF_FIBER

    @staticmethod
    def _get_of_speed(entry):
        speed = IetfInterfacesState._get_speed_value(entry)
        speed_map = {
            1000000000: OFPPF_1GB_FD,
            10000000000: OFPPF_10GB_FD,
            40000000000: OFPPF_40GB_FD,
            100000000000: OFPPF_100GB_FD,
        }
        # return speed_map.get(speed, OFPPF_OTHER)
        # TODO: For now, force 100 GB
        return OFPPF_100GB_FD

    @staticmethod
    def _get_port_number(name, if_index):
        import re

        formats = [
            'xpon \d/{1,2}\d',                          # OLT version 3 (Feb 2018++)
            'Hundred-Gigabit-Ethernet \d/\d/{1,2}\d',   # OLT version 2
            'XPON \d/\d/{1,2}\d',                       # OLT version 2
            'hundred-gigabit-ethernet \d/{1,2}\d',      # OLT version 1
            'channel-termination {1,2}\d',              # OLT version 1
        ]
        p2 = re.compile('\d+')

        for regex in formats:
            p = re.compile(regex, re.IGNORECASE)
            match = p.match(name)
            if match is not None:
                return int(p2.findall(name)[-1])

    @staticmethod
    def get_port_entries(rpc_reply, port_type):
        """
        Get the port entries that make up the northbound and
        southbound interfaces

        :param rpc_reply:
        :param port_type:
        :return:
        """
        ports = dict()
        result_dict = xmltodict.parse(rpc_reply.data_xml)
        entries = result_dict['data']['interfaces-state']['interface']
        if not isinstance(entries, list):
            entries = [entries]
        port_entries = [entry for entry in entries if 'name' in entry and
                        port_type.lower() in entry['name'].lower()]

        for entry in port_entries:
            port = {
                'port_no': IetfInterfacesState._get_port_number(entry.get('name'),
                                                                entry.get('ifindex')),
                'name': entry.get('name', 'unknown'),
                'ifIndex': entry.get('ifIndex'),
                # 'label': None,
                'mac_address': IetfInterfacesState._get_mac_addr(entry),
                'admin_state': IetfInterfacesState._get_admin_state(entry),
                'oper_status': IetfInterfacesState._get_oper_status(entry),
                'ofp_state': IetfInterfacesState._get_of_state(entry),
                'ofp_capabilities': IetfInterfacesState._get_of_capabilities(entry),
                'current_speed': IetfInterfacesState._get_of_speed(entry),
                'max_speed': IetfInterfacesState._get_of_speed(entry),
            }
            port_no = port['port_no']
            if port_no not in ports:
                ports[port_no] = port
            else:
                ports[port_no].update(port)

        return ports
