# Copyright 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.

import structlog

log = structlog.get_logger()


class OltConfig(object):
    """
    Class to wrap decode of olt container (config) from the ADTRAN
    gpon-olt-hw.yang YANG model
    """
    def __init__(self, packet):
        self._packet = packet
        self._pons = None

    def __str__(self):
        return "OltConfig: {}".format(self.olt_id)

    @property
    def olt_id(self):
        """Unique OLT identifier"""
        return self._packet.get('olt-id', '')

    @property
    def debug_output(self):
        """least important level that will output everything"""
        return self._packet.get('debug-output', 'warning')

    @property
    def pons(self):
        if self._pons is None:
            self._pons = OltConfig.Pon.decode(self._packet.get('pon', None))
        return self._pons

    class Pon(object):
        """
        Provides decode of PON list from within
        """
        def __init__(self, packet):
            assert 'pon-id' in packet, 'pon-id not found'
            self._packet = packet
            self._onus = None

        def __str__(self):
            return "OltConfig.Pon: pon-id: {}".format(self.pon_id)

        @staticmethod
        def decode(pon_list):
            pons = {}

            if pon_list is not None:
                for pon_data in pon_list:
                    pon = OltConfig.Pon(pon_data)
                    assert pon.pon_id not in pons
                    pons[pon.pon_id] = pon

            return pons

        @property
        def pon_id(self):
            """PON identifier"""
            return self._packet['pon-id']

        @property
        def enabled(self):
            """The desired state of the interface"""
            return self._packet.get('enabled', False)

        @property
        def downstream_fec_enable(self):
            """Enables downstream Forward Error Correction"""
            return self._packet.get('downstream-fec-enable', False)

        @property
        def upstream_fec_enable(self):
            """Enables upstream Forward Error Correction"""
            return self._packet.get('upstream-fec-enable', False)

        @property
        def deployment_range(self):
            """Maximum deployment distance (meters)"""
            return self._packet.get('deployment-range', 25000)

        @property
        def onus(self):
            if self._onus is None:
                self._onus = OltConfig.Pon.Onu.decode(self._packet.get('onus', None))
            return self._onus

        class Onu(object):
            """
            Provides decode of onu list for a PON port
            """
            def __init__(self, packet):
                assert 'onu-id' in packet, 'onu-id not found'
                self._packet = packet
                self._tconts = None
                self._tconts_dict = None
                self._gem_ports = None
                self._gem_ports_dict = None

            def __str__(self):
                return "OltConfig.Pon.Onu: onu-id: {}".format(self.onu_id)

            @staticmethod
            def decode(onu_dict):
                onus = {}

                if onu_dict is not None:
                    if 'onu' in onu_dict:
                        for onu_data in onu_dict['onu']:
                            onu = OltConfig.Pon.Onu(onu_data)
                            assert onu.onu_id not in onus
                            onus[onu.onu_id] = onu
                    elif len(onu_dict) > 0 and 'onu-id' in onu_dict[0]:
                        onu = OltConfig.Pon.Onu(onu_dict[0])
                        assert onu.onu_id not in onus
                        onus[onu.onu_id] = onu

                return onus

            @property
            def onu_id(self):
                """The ID used to identify the ONU"""
                return self._packet['onu-id']

            @property
            def serial_number_64(self):
                """The serial number (base-64) is unique for each ONU"""
                return self._packet.get('serial-number', '')

            @property
            def password(self):
                """ONU Password"""
                return self._packet.get('password', bytes(0))

            @property
            def enable(self):
                """If true, places the ONU in service"""
                return self._packet.get('enable', False)

            @property
            def tconts(self):
                if self._tconts is None:
                    self._tconts = OltConfig.Pon.Onu.TCont.decode(self._packet.get('t-conts', None))
                return self._tconts

            @property
            def tconts_dict(self):               # TODO: Remove if not used
                if self._tconts_dict is None:
                    self._tconts_dict = {tcont.alloc_id: tcont for tcont in self.tconts}
                return self._tconts_dict

            @property
            def gem_ports(self):
                if self._gem_ports is None:
                    self._gem_ports = OltConfig.Pon.Onu.GemPort.decode(self._packet.get('gem-ports', None))
                return self._gem_ports

            @property
            def gem_ports_dict(self):               # TODO: Remove if not used
                if self._gem_ports_dict is None:
                    self._gem_ports_dict = {gem.gem_id: gem for gem in self.gem_ports}
                return self._gem_ports_dict

            class TCont(object):
                """
                Provides decode of onu list for the T-CONT container
                """
                def __init__(self, packet):
                    assert 'alloc-id' in packet, 'alloc-id not found'
                    self._packet = packet
                    self._traffic_descriptor = None
                    self._best_effort = None

                def __str__(self):
                    return "OltConfig.Pon.Onu.TCont: alloc-id: {}".format(self.alloc_id)

                @staticmethod
                def decode(tcont_container):
                    tconts = {}

                    if tcont_container is not None:
                        for tcont_data in tcont_container.get('t-cont', []):
                            tcont = OltConfig.Pon.Onu.TCont(tcont_data)
                            assert tcont.alloc_id not in tconts
                            tconts[tcont.alloc_id] = tcont

                    return tconts

                @property
                def alloc_id(self):
                    """The ID used to identify the T-CONT"""
                    return self._packet['alloc-id']

                @property
                def traffic_descriptor(self):
                    """
                    Each Alloc-ID is provisioned with a traffic descriptor that specifies
                    the three bandwidth component parameters: fixed bandwidth, assured
                    bandwidth, and maximum bandwidth, as well as the ternary eligibility
                    indicator for additional bandwidth assignment
                    """
                    if self._traffic_descriptor is None and 'traffic-descriptor' in self._packet:
                        self._traffic_descriptor = OltConfig.Pon.Onu.TCont.\
                            TrafficDescriptor(self._packet['traffic-descriptor'])
                    return self._traffic_descriptor

                class TrafficDescriptor(object):
                    def __init__(self, packet):
                        self._packet = packet

                    def __str__(self):
                        return "OltConfig.Pon.Onu.TCont.TrafficDescriptor: {}/{}/{}".\
                            format(self.fixed_bandwidth, self.assured_bandwidth,
                                   self.maximum_bandwidth)

                    @property
                    def fixed_bandwidth(self):
                        try:
                            return int(self._packet.get('fixed-bandwidth', 0))
                        except:
                            return 0

                    @property
                    def assured_bandwidth(self):
                        try:
                            return int(self._packet.get('assured-bandwidth', 0))
                        except:
                            return 0

                    @property
                    def maximum_bandwidth(self):
                        try:
                            return int(self._packet.get('maximum-bandwidth', 0))
                        except:
                            return 0

                    @property
                    def additional_bandwidth_eligibility(self):
                        return self._packet.get('additional-bandwidth-eligibility', 'none')

                @property
                def best_effort(self):
                    if self._best_effort is None:
                        self._best_effort = OltConfig.Pon.Onu.TCont.BestEffort.decode(
                            self._packet.get('best-effort', None))
                    return self._best_effort

                class BestEffort(object):
                    def __init__(self, packet):
                        self._packet = packet

                    def __str__(self):
                        return "OltConfig.Pon.Onu.TCont.BestEffort: {}".format(self.bandwidth)

                    @property
                    def bandwidth(self):
                        return self._packet['bandwidth']

                    @property
                    def priority(self):
                        return self._packet['priority']

                    @property
                    def weight(self):
                        return self._packet['weight']

            class GemPort(object):
                """
                Provides decode of onu list for the gem-ports container
                """
                def __init__(self, packet):
                    assert 'port-id' in packet, 'port-id not found'
                    self._packet = packet

                def __str__(self):
                    return "OltConfig.Pon.Onu.GemPort: port-id: {}/{}".\
                        format(self.port_id, self.alloc_id)

                @staticmethod
                def decode(gem_port_container):
                    gem_ports = {}

                    if gem_port_container is not None:
                        for gem_port_data in gem_port_container.get('gem-port', []):
                            gem_port = OltConfig.Pon.Onu.GemPort(gem_port_data)
                            assert gem_port.port_id not in gem_ports
                            gem_ports[gem_port.port_id] = gem_port

                    return gem_ports

                @property
                def port_id(self):
                    """The ID used to identify the GEM Port"""
                    return self._packet['port-id']

                @property
                def gem_id(self):
                    """The ID used to identify the GEM Port"""
                    return self.port_id

                @property
                def alloc_id(self):
                    """The Alloc-ID of the T-CONT to which this GEM port is mapped"""
                    return self._packet['alloc-id']

                @property
                def omci_transport(self):
                    """If true, this GEM port is used to transport the OMCI virtual connection"""
                    return self._packet.get('omci-transport', False)

                @property
                def encryption(self):
                    """If true, enable encryption using the advanced encryption standard(AES)"""
                    return self._packet.get('encryption', False)
