#
# 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.
#
import structlog

from voltha.protos.device_pb2 import Image
from omci_entities import *
from database.mib_db_api import *
from enum import IntEnum


class OMCCVersion(IntEnum):
    Unknown                 = 0     # Unknown or unsupported version
    G_984_4                 = 0x80  # (06/04)
    G_984_4_2005_Amd_1      = 0x81  # Amd.1 (06/05)
    G_984_4_2006_Amd_2      = 0x82  # Amd.2 (03/06)
    G_984_4_2006_Amd_3      = 0x83  # Amd.3 (12/06)
    G_984_4_2008            = 0x84  # (02/08)
    G_984_4_2009_Amd_1      = 0x85  # Amd.1 (06/09)
    G_984_4_2009_Amd_2_Base = 0x86  # Amd.2 (2009)  Baseline message set only, w/o the extended message set option
    G_984_4_2009_Amd_2      = 0x96  # Amd.2 (2009)  Extended message set option +  baseline message set.
    G_988_2010_Base         = 0xA0  # (2010) Baseline message set only, w/o the extended message set option
    G_988_2011_Amd_1_Base   = 0xA1  # Amd.1 (2011) Baseline message set only
    G_988_2012_Amd_2_Base   = 0xA2  # Amd.2 (2012) Baseline message set only
    G_988_2012_Base         = 0xA3  # (2012) Baseline message set only
    G_988_2010              = 0xB0  # (2010) Baseline and extended message set
    G_988_2011_Amd_1        = 0xB1  # Amd.1 (2011) Baseline and extended message set
    G_988_2012_Amd_2        = 0xB2  # Amd.2 (2012) Baseline and extended message set
    G_988_2012              = 0xB3  # (2012)Baseline and extended message set

    @staticmethod
    def values():
        return {OMCCVersion[member].value for member in OMCCVersion.__members__.keys()}

    @staticmethod
    def to_enum(value):
        return next((v for k, v in OMCCVersion.__members__.items()
                     if v.value == value), OMCCVersion.Unknown)


class OnuConfiguration(object):
    """
    Utility class to query OMCI MIB Database for various ONU/OMCI Configuration
    and capabilties. These capabilities revolve around read-only MEs discovered
    during the MIB Upload process.

    There is also a 'omci_onu_capabilities' State Machine and an
    'onu_capabilities_task.py' OMCI Task that will query the ONU, via the
    OMCI (ME#287) Managed entity to get the full list of supported OMCI ME's
    and available actions/message-types supported.

    NOTE: Currently this class is optimized/tested for ONUs that support the
          OpenOMCI implementation.
    """
    def __init__(self, omci_agent, device_id):
        """
        Initialize this instance of the OnuConfiguration class

        :param omci_agent: (OpenOMCIAgent) agent reference
        :param device_id: (str) ONU Device ID

        :raises KeyError: If ONU Device is not registered with OpenOMCI
        """
        self.log = structlog.get_logger(device_id=device_id)
        self._device_id = device_id
        self._onu_device = omci_agent.get_device(device_id)

        # The capabilities
        self._attributes = None
        self.reset()

    def _get_capability(self, attr, class_id, instance_id=None):
        """
        Get the OMCI capabilities for this device

        :param attr: (str) OnuConfiguration attribute field
        :param class_id: (int) ME Class ID
        :param instance_id: (int) Instance ID. If not provided, all instances of the
                            specified class ID are returned if present in the DB.

        :return: (dict) Class and/or Instances. None is returned if the CLASS is not present
        """
        try:
            assert self._onu_device.mib_synchronizer.last_mib_db_sync is not None, \
                'MIB Database for ONU {} has never been synchronized'.format(self._device_id)

            # Get the requested information
            if self._attributes[attr] is None:
                value = self._onu_device.query_mib(class_id, instance_id=instance_id)

                if isinstance(value, dict) and len(value) > 0:
                    self._attributes[attr] = value

            return self._attributes[attr]

        except Exception as e:
            self.log.exception('onu-capabilities', e=e, class_id=class_id,
                               instance_id=instance_id)
            raise

    def reset(self):
        """
        Reset the cached database entries to None.  This method should be
        called after any communications loss to the ONU (reboot, PON down, ...)
        in case a new software load with different capabilities is available.
        """
        self._attributes = {
            '_ont_g': None,
            '_ont_2g': None,
            '_ani_g': None,
            '_uni_g': None,
            '_cardholder': None,
            '_circuit_pack': None,
            '_software': None,
            '_pptp': None,
            '_veip': None
        }

    @property
    def version(self):
        """
        This attribute identifies the version of the ONU as defined by the vendor
        """
        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
        if ontg is None or ATTRIBUTES_KEY not in ontg:
            return None

        return ontg[ATTRIBUTES_KEY].get('version')

    @property
    def serial_number(self):
        """
        The serial number is unique for each ONU
        """
        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
        if ontg is None or ATTRIBUTES_KEY not in ontg:
            return None

        return ontg[ATTRIBUTES_KEY].get('serial_number')

    @property
    def traffic_management_option(self):
        """
        This attribute identifies the upstream traffic management function
        implemented in the ONU. There are three options:

            0 Priority controlled and flexibly scheduled upstream traffic. The traffic
              scheduler and priority queue mechanism are used for upstream traffic.

            1 Rate controlled upstream traffic. The maximum upstream traffic of each
              individual connection is guaranteed by shaping.

            2 Priority and rate controlled. The traffic scheduler and priority queue
              mechanism are used for upstream traffic. The maximum upstream traffic
              of each individual connection is guaranteed by shaping.
        """
        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
        if ontg is None or ATTRIBUTES_KEY not in ontg:
            return None

        return ontg[ATTRIBUTES_KEY].get('traffic_management_option')

    @property
    def onu_survival_time(self):
        """
        This attribute indicates the minimum guaranteed time in milliseconds
        between the loss of external power and the silence of the ONU. This does not
        include survival time attributable to a backup battery. The value zero implies that
        the actual time is not known.

        Optional
        """
        ontg = self._get_capability('_ont_g', OntG.class_id, 0)
        if ontg is None or ATTRIBUTES_KEY not in ontg:
            return None

        return ontg[ATTRIBUTES_KEY].get('onu_survival_time', 0)

    @property
    def equipment_id(self):
        """
        This attribute may be used to identify the specific type of ONU. In some
        environments, this attribute may include the equipment CLEI code.
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('equipment_id')

    @property
    def omcc_version(self):
        """
        This attribute identifies the version of the OMCC protocol being used by the
        ONU. This allows the OLT to manage a network with ONUs that support different
        OMCC versions. Release levels of [ITU-T G.984.4] are supported with code
        points of the form 0x8y and 0x9y, where y is a hexadecimal digit in the range
        0..F.  Support for continuing revisions of this Recommendation is defined in
        the 0xAy range.
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return OMCCVersion.to_enum(ont2g[ATTRIBUTES_KEY].get('omcc_version', 0))

    @property
    def vendor_product_code(self):
        """
        This attribute contains a vendor-specific product code for the ONU
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('vendor_product_code')

    @property
    def total_priority_queues(self):
        """
        This attribute reports the total number of upstream priority queues
        that are not associated with a circuit pack, but with the ONU in its entirety
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('total_priority_queue_number')

    @property
    def total_traffic_schedulers(self):
        """
        This attribute reports the total number of traffic schedulers that
        are not associated with a circuit pack, but with the ONU in its entirety.
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('total_traffic_scheduler_number')

    @property
    def total_gem_ports(self):
        """
        This attribute reports the total number of GEM port-IDs supported
        by the ONU.
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('total_gem_port_id_number')

    @property
    def uptime(self):
        """
        This attribute counts 10 ms intervals since the ONU was last initialized.
        It rolls over to 0 when full
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('sys_uptime')

    @property
    def connectivity_capability(self):
        """
        This attribute indicates the Ethernet connectivity models that the ONU
        can support. The value 0 indicates that the capability is not supported; 1 signifies
        support.

             Bit    Model [Figure reference ITU-T 988]
              1     (LSB) N:1 bridging, Figure 8.2.2-3
              2     1:M mapping, Figure 8.2.2-4
              3     1:P filtering, Figure 8.2.2-5
              4     N:M bridge-mapping, Figure 8.2.2-6
              5     1:MP map-filtering, Figure 8.2.2-7
              6     N:P bridge-filtering, Figure 8.2.2-8
              7  to refer to    N:MP bridge-map-filtering, Figure 8.2.2-9
            8...16  Reserved
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('connectivity_capability')

    @property
    def qos_configuration_flexibility(self):
        """
        This attribute reports whether various managed entities in the
        ONU are fixed by the ONU's architecture or whether they are configurable. For
        backward compatibility, and if the ONU does not support this attribute, all such
        attributes are understood to be hard-wired.

            Bit      Interpretation when bit value = 1
             1 (LSB) Priority queue ME: Port field of related port attribute is
                     read-write and can point to any T-CONT or UNI port in the
                     same slot
             2       Priority queue ME: The traffic scheduler pointer is permitted
                     to refer to any other traffic scheduler in the same slot
             3       Traffic scheduler ME: T-CONT pointer is read-write
             4       Traffic scheduler ME: Policy attribute is read-write
             5       T-CONT ME: Policy attribute is read-write
             6       Priority queue ME: Priority field of related port attribute is
                     read-write
             7..16   Reserved
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('qos_configuration_flexibility')

    @property
    def priority_queue_scale_factor(self):
        """
        This specifies the scale factor of several attributes of the priority
        queue managed entity of section 5.2.8
        """
        ont2g = self._get_capability('_ont_2g', Ont2G.class_id, 0)
        if ont2g is None or ATTRIBUTES_KEY not in ont2g:
            return None

        return ont2g[ATTRIBUTES_KEY].get('priority_queue_scale_factor', 1)

    @property
    def cardholder_entities(self):
        """
        Return a dictionary containing some overall information on the CardHolder
        instances for this ONU.
        """
        ch = self._get_capability('_cardholder', Cardholder.class_id)
        results = dict()

        if ch is not None:
            for inst, inst_data in ch.items():
                if isinstance(inst, int):
                    results[inst] = {
                        'entity-id':              inst,
                        'is-single-piece':        inst >= 256,
                        'slot-number':            inst & 0xff,
                        'actual-plug-in-type':    inst_data[ATTRIBUTES_KEY].get('actual_plugin_unit_type', 0),
                        'actual-equipment-id':    inst_data[ATTRIBUTES_KEY].get('actual_equipment_id', 0),
                        'protection-profile-ptr': inst_data[ATTRIBUTES_KEY].get('protection_profile_pointer', 0),
                    }
        return results if len(results) else None

    @property
    def circuitpack_entities(self):
        """
        This specifies the scale factor of several attributes of the priority
        queue managed entity of section 5.2.8
        """
        cp = self._get_capability('_circuit_pack', CircuitPack.class_id)
        results = dict()

        if cp is not None:
            for inst, inst_data in cp.items():
                if isinstance(inst, int):
                    results[inst] = {
                        'entity-id': inst,
                        'number-of-ports': inst_data[ATTRIBUTES_KEY].get('number_of_ports', 0),
                        'serial-number': inst_data[ATTRIBUTES_KEY].get('serial_number', 0),
                        'version': inst_data[ATTRIBUTES_KEY].get('version', 0),
                        'vendor-id': inst_data[ATTRIBUTES_KEY].get('vendor_id', 0),
                        'total-tcont-count': inst_data[ATTRIBUTES_KEY].get('total_tcont_buffer_number', 0),
                        'total-priority-queue-count': inst_data[ATTRIBUTES_KEY].get('total_priority_queue_number', 0),
                        'total-traffic-sched-count': inst_data[ATTRIBUTES_KEY].get('total_traffic_scheduler_number', 0),
                    }

        return results if len(results) else None

    @property
    def software_images(self):
        """
        Get a list of software image information for the ONU.  The information is provided
        so that it may be directly added to the protobuf Device information software list.
        """
        sw = self._get_capability('_software', SoftwareImage.class_id)
        images = list()

        if sw is not None:
            for inst, inst_data in sw.items():
                if isinstance(inst, int):
                    is_active = inst_data[ATTRIBUTES_KEY].get('is_active', False)

                    images.append(Image(name='running-revision' if is_active else 'candidate-revision',
                                        version=str(inst_data[ATTRIBUTES_KEY].get('version',
                                                                                  'Not Available').rstrip('\0')),
                                        is_active=is_active,
                                        is_committed=inst_data[ATTRIBUTES_KEY].get('is_committed',
                                                                                   False),
                                        is_valid=inst_data[ATTRIBUTES_KEY].get('is_valid',
                                                                               False),
                                        install_datetime='Not Available',
                                        hash=str(inst_data[ATTRIBUTES_KEY].get('image_hash',
                                                                               'Not Available').rstrip('\0'))))
        return images if len(images) else None

    @property
    def ani_g_entities(self):
        """
        This managed entity organizes data associated with each access network
        interface supported by a G-PON ONU. The ONU automatically creates one
        instance of this managed entity for each PON physical port.
        """
        ag = self._get_capability('_ani_g', AniG.class_id)
        results = dict()

        if ag is not None:
            for inst, inst_data in ag.items():
                if isinstance(inst, int):
                    results[inst] = {
                        'entity-id':               inst,
                        'slot-number':             (inst >> 8) & 0xff,
                        'port-number':             inst & 0xff,
                        'total-tcont-count':       inst_data[ATTRIBUTES_KEY].get('total_tcont_number', 0),
                        'piggyback-dba-reporting': inst_data[ATTRIBUTES_KEY].get('piggyback_dba_reporting', 0),
                    }
        return results if len(results) else None

    @property
    def uni_g_entities(self):
        """
        This managed entity organizes data associated with user network interfaces
        (UNIs) supported by GEM. One instance of the UNI-G managed entity exists
        for each UNI supported by the ONU.

        The ONU automatically creates or deletes instances of this managed entity
        upon the creation or deletion of a real or virtual circuit pack managed
        entity, one per port.
        """
        ug = self._get_capability('_uni_g', UniG.class_id)
        results = dict()

        if ug is not None:
            for inst, inst_data in ug.items():
                if isinstance(inst, int):
                    results[inst] = {
                        'entity-id':               inst,
                        'management-capability':   inst_data[ATTRIBUTES_KEY].get('management_capability', 0)
                    }
        return results if len(results) else None

    @property
    def pptp_entities(self):
        """
        Returns discovered PPTP Ethernet entities.  TODO more detail here
        """
        pptp = self._get_capability('_pptp', PptpEthernetUni.class_id)
        results = dict()

        if pptp is not None:
            for inst, inst_data in pptp.items():
                if isinstance(inst, int):
                    results[inst] = {
                        'entity-id':                inst,
                        'expected-type':            inst_data[ATTRIBUTES_KEY].get('expected_type', 0),
                        'sensed-type':              inst_data[ATTRIBUTES_KEY].get('sensed_type', 0),
                        'autodetection-config':     inst_data[ATTRIBUTES_KEY].get('auto_detection_configuration', 0),
                        'ethernet-loopback-config': inst_data[ATTRIBUTES_KEY].get('ethernet_loopback_configuration', 0),
                        'administrative-state':     inst_data[ATTRIBUTES_KEY].get('administrative_state', 0),
                        'operational-state':        inst_data[ATTRIBUTES_KEY].get('operational_state', 0),
                        'config-ind':               inst_data[ATTRIBUTES_KEY].get('configuration_ind', 0),
                        'max-frame-size':           inst_data[ATTRIBUTES_KEY].get('max_frame_size', 0),
                        'dte-dce-ind':              inst_data[ATTRIBUTES_KEY].get('dte_or_dce_ind', 0),
                        'pause-time':               inst_data[ATTRIBUTES_KEY].get('pause_time', 0),
                        'bridged-ip-ind':           inst_data[ATTRIBUTES_KEY].get('bridged_or_ip_ind', 0),
                        'arc':                      inst_data[ATTRIBUTES_KEY].get('arc', 0),
                        'arc-interval':             inst_data[ATTRIBUTES_KEY].get('arc_interval', 0),
                        'pppoe-filter':             inst_data[ATTRIBUTES_KEY].get('ppoe_filter', 0),
                        'power-control':            inst_data[ATTRIBUTES_KEY].get('power_control', 0)
                    }
        return results if len(results) else None

    @property
    def veip_entities(self):
        """
        Returns discovered VEIP entities.  TODO more detail here
        """
        veip = self._get_capability('_veip', VeipUni.class_id)
        results = dict()

        if veip is not None:
            for inst, inst_data in veip.items():
                if isinstance(inst, int):
                    results[inst] = {
                        'entity-id':                inst,
                        'administrative-state':     inst_data[ATTRIBUTES_KEY].get('administrative_state', 0),
                        'operational-state':        inst_data[ATTRIBUTES_KEY].get('operational_state', 0),
                        'interdomain-name':         inst_data[ATTRIBUTES_KEY].get('interdomain_name', ""),
                        'tcp-udp-pointer':          inst_data[ATTRIBUTES_KEY].get('tcp_udp_pointer', 0),
                        'iana-assigned-port':       inst_data[ATTRIBUTES_KEY].get('iana_assigned_port', 0)
                    }
        return results if len(results) else None
