#
# Copyright 2017 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 struct import pack, unpack

from scapy.automaton import ATMT
import structlog
from voltha.adapters.microsemi_olt.BaseOltAutomaton import BaseOltAutomaton
from voltha.adapters.microsemi_olt.PAS5211 import PAS5211EventOnuActivation, PAS5211MsgGetActivationAuthMode, \
    PAS5211MsgGetActivationAuthModeResponse, PAS5211MsgSetOnuOmciPortId, \
    PAS5211MsgSetOnuOmciPortIdResponse, PAS5211MsgSendFrame, PAS5211MsgSendFrameResponse, \
    PAS5211MsgGetLogicalObjectStatus, PAS5211MsgGetLogicalObjectStatusResponse, PAS5211MsgSetOnuAllocId, \
    PAS5211MsgGetDbaMode, PAS5211MsgGetDbaModeResponse, PAS5211MsgSendDbaAlgorithmMsg, \
    PAS5211MsgSendDbaAlgorithmMsgResponse, PAS5211EventDbaAlgorithm, PAS5211MsgSetPortIdConfig, \
    PAS5211MsgSetPortIdConfigResponse, PAS5211MsgGetOnuIdByPortId, PAS5211MsgGetOnuIdByPortIdResponse, \
    PAS5211SetVlanUplinkConfiguration, PAS5211SetVlanUplinkConfigurationResponse, PAS5211MsgSetOnuAllocIdResponse
from voltha.adapters.microsemi_olt.PAS5211_constants import PON_ACTIVATION_AUTH_AUTO, PON_ENABLE, PON_PORT_PON, \
    PON_LOGICAL_OBJECT_TYPE_ALLOC_ID, PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID, PON_TRUE, \
    PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU, PMC_OFAL_START_FLOW_ID_BASE, PON_DBA_MODE_RUNNING, \
    PYTHAGORAS_UPDATE_AID_SLA, SLA_be_bw_gros, SLA_gr_bw_gros, SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS, \
    PYTHAGORAS_DBA_STATUS_REPORT_NSR, PYTHAGORAS_SET_SLA_RESP_SIZE, PON_PORT_TYPE_GEM, PON_PORT_DESTINATION_CNI0, \
    PON_FALSE, PON_DISABLE
from voltha.extensions.omci.omci_entities import CircuitPack
from voltha.extensions.omci.omci_frame import OmciFrame
from voltha.extensions.omci.omci_messages import OmciGet, OmciGetResponse
from voltha.protos.common_pb2 import AdminState
from voltha.protos.common_pb2 import OperStatus
from voltha.protos.device_pb2 import Port

log = structlog.get_logger()
_verbose = False

ALLOC_ID = 1000

def alloc_id(onu_id):
    for i in range(0, PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU):
        alloc_id = PMC_OFAL_START_FLOW_ID_BASE + \
                   (onu_id * PMC_OFAL_MAX_BI_DIRECTIONAL_FLOW_PER_ONU) + i
        yield alloc_id

def hexstring(string):
    return ":".join("{:02x}".format(ord(c)) for c in string)

class ActivationManager(BaseOltAutomaton):

    onu_id = None
    serial_number = None
    onu_session_id = None
    port_id = None
    channel_id = None
    alloc_id = None
    vendor = None

    def parse_args(self, debug=0, store=0, **kwargs):
        self.onu_id = kwargs.pop('onu_id')
        self.serial_number = kwargs.pop('serial_number')
        self.onu_session_id = kwargs.pop('onu_session_id')
        self.port_id = self.onu_id
        self.channel_id = kwargs.pop('channel_id')
        self.alloc_id = alloc_id(self.onu_id)

        if self.onu_id is None or self.serial_number is None or \
                self.onu_session_id is None or self.channel_id is None:
            raise ValueError('ONU is not well defined')

        BaseOltAutomaton.parse_args(self, debug=debug, store=store, **kwargs)

    """
    States
    """

    @ATMT.state(initial=1)
    def got_activation_event(self):
        pass

    @ATMT.state()
    def wait_get_auth_mode(self):
        pass

    @ATMT.state()
    def got_auth_mode(self):
        pass

    @ATMT.state()
    def wait_omci_port_id(self):
        pass

    @ATMT.state()
    def got_omci_port_id(self):
        pass

    @ATMT.state()
    def wait_send_frame(self):
        pass

    @ATMT.state()
    def wait_omci_get(self):
        pass

    @ATMT.state()
    def wait_logical_object_status(self):
        pass

    @ATMT.state()
    def wait_set_alloc_id(self):
        pass

    @ATMT.state()
    def wait_dba_mode(self):
        pass

    @ATMT.state()
    def wait_send_dba_alg_msg(self):
        pass

    @ATMT.state()
    def wait_dba_alg_event(self):
        pass

    @ATMT.state()
    def wait_set_port_id_config(self):
        pass

    @ATMT.state()
    def wait_get_onu_id_by_port_id(self):
        pass

    @ATMT.state()
    def wait_set_vlan_uplink_config(self):
        pass

    @ATMT.state(final=1)
    def end(self):
        pass

    @ATMT.state(error=1)
    def error(self, msg):
        log.error(msg)

    """
    Utility Methods
    """

    def create_port(self, vendor):
        port = Port(port_no=self.port_id,
                    label="{} ONU".format(vendor),
                    type=Port.ETHERNET_UNI,
                    admin_state=AdminState.ENABLED,
                    oper_status=OperStatus.ACTIVE
        )
        self.device.add_port(port)

    def px(self, pkt):
        return self.p(pkt, channel_id=self.channel_id,
                      onu_id=self.onu_id, onu_session_id=self.onu_session_id)

    def error(self, msg):
        log.error(msg)
        raise self.error()

    def detect_onu(self):
        log.info("Activated {} ONT".format(self.vendor))
        self.create_port(self.vendor)
        print self.channel_id
        print self.onu_id
        try:
            self.device.onu_detected(
                parent_port_no=self.channel_id,
                child_device_type='%s_onu' % self.vendor.lower(),
                onu_id=self.onu_id,
                serial_number=hexstring(self.serial_number)
            )
        except Exception as e:
            print e

    """
    Transitions
    """

    # Transition from got_activation_event
    @ATMT.condition(got_activation_event)
    def send_get_activation_auth_mode(self):
        auth_mode = PAS5211MsgGetActivationAuthMode()
        self.send(self.p(auth_mode))
        raise self.wait_get_auth_mode()

    # Transitions from wait_get_auth_mode
    @ATMT.timeout(wait_get_auth_mode, 3)
    def timeout_get_auth_mode(self):
        raise self.error('Could not get auth mode for OLT {}; dropping activation event for {}'
                   .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_get_auth_mode)
    def wait_for_get_auth_mode(self, pkt):
        if PAS5211MsgGetActivationAuthModeResponse in pkt:
            if pkt.mode == PON_ACTIVATION_AUTH_AUTO:
                raise self.got_auth_mode()
            else:
                # TODO There may be something that can be done here.
                # See line 2497 of PAS_onu_mode_change_thread.c
                log.error('Got unknown auth mode {}; dropping activation event'.format(pkt.mode))
                raise self.end()

    # Transitions from got auth_mode
    @ATMT.condition(got_auth_mode)
    def send_omci_port_id(self):
        omci_port_id = PAS5211MsgSetOnuOmciPortId(port_id=self.port_id, activate=PON_ENABLE)
        self.send(self.px(omci_port_id))
        raise self.wait_omci_port_id()

    # Transitions from wait_omci_port_id
    @ATMT.timeout(wait_omci_port_id, 3)
    def timeout_omci_port_id(self):
        raise self.error('Could not set omci port id for OLT {}; dropping activation event for {}'
                   .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_omci_port_id)
    def wait_for_omci_port_id(self, pkt):
        if pkt.opcode == PAS5211MsgSetOnuOmciPortIdResponse.opcode and \
                pkt.onu_id == self.onu_id and pkt.onu_session_id == self.onu_session_id and \
                pkt.channel_id == self.channel_id:
            raise self.got_omci_port_id()

    # Transitions from got_omci_port_id
    @ATMT.condition(got_omci_port_id)
    def send_omci_identity_frame(self):
        # attr_mask |= OMCI_ATTR_BIT(OMCI_CIRCUIT_PACK_ATTR_VENDOR_ID);
        #message.attributes_mask = 2048

        # Entity_id
        # equip_ind = OMCI_CIRCUIT_PACK_INTEGRATED_EQUIPMENT;
        # slot_id = 257;
        # entity_instance = ((equip_ind<<8) | slot_id
        message = OmciGet(entity_class=CircuitPack.class_id, entity_id = 257,
                          attributes_mask=2048)
        #TODO fix transaction id
        frame = OmciFrame(transaction_id=0, message_type=OmciGet.message_id,
                          omci_message=message)
        omci_frame = PAS5211MsgSendFrame(port_type=PON_PORT_PON, port_id=self.port_id,
                                         management_frame=PON_ENABLE, frame=frame)


        self.send(self.px(omci_frame))

        raise self.wait_send_frame()

    # Transitions from wait_send_frame
    @ATMT.timeout(wait_send_frame, 3)
    def timeout_send_frame(self):
        raise self.error('Could not send omci to OLT {}; dropping activation event for {}'
                   .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_send_frame)
    def wait_for_send_frame(self, pkt):
        if PAS5211MsgSendFrameResponse in pkt:
            raise self.wait_omci_get()

    # Transitions from wait_omci_get
    @ATMT.timeout(wait_omci_get, 3)
    def timeout_send_frame(self):
        raise self.error('Did not receive omci get event from OLT {}; dropping activation event for {}'
                   .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_omci_get)
    def wait_for_omci_get(self, pkt):
        if OmciGetResponse in pkt:
            self.allocId = self.alloc_id.next()
            self.vendor = pkt['OmciGetResponse'].data['vendor_id']
            l_obj_status = PAS5211MsgGetLogicalObjectStatus(
                            type=PON_LOGICAL_OBJECT_TYPE_ALLOC_ID,
                            value=self.allocId)
            self.send(self.px(l_obj_status))
            raise self.wait_logical_object_status()

    # Transitions from wait_logical_object_status
    @ATMT.timeout(wait_logical_object_status, 3)
    def timeout_logical_object_status(self):
        raise self.error('Did not receive info about alloc id status for {}; dropping activation event for {}'
                   .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_logical_object_status)
    def wait_for_logical_object_status(self, pkt):
        if PAS5211MsgGetLogicalObjectStatusResponse in pkt:
            if pkt.type == PON_LOGICAL_OBJECT_TYPE_ALLOC_ID:
                if pkt.return_value == 0:
                    # alloc-id not set
                    set_alloc_id = PAS5211MsgSetOnuAllocId(
                                    alloc_id=self.allocId,
                                    allocate=PON_ENABLE
                                )
                    self.onu_id = -1
                    self.port_id = self.allocId
                    self.send(self.px(set_alloc_id))
                    raise self.wait_set_alloc_id()
                else:
                    l_obj_status = PAS5211MsgGetLogicalObjectStatus(
                        type=PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID,
                        value=self.allocId)
                    self.send(self.px(l_obj_status))
                    raise self.wait_logical_object_status()
            elif pkt.type == PON_LOGICAL_OBJECT_TYPE_ONU_ID_BY_ALLOC_ID:
                # That's your onu id.
                self.onu_id = pkt.return_value
                # FIXME Need to iterate to get the port id as
                # in PMC_OFAL_flow_db.c line 656
                # UPDATE PORT_ID
                set_alloc_id = PAS5211MsgSetOnuAllocId(
                    alloc_id=self.allocId,
                    allocate=PON_ENABLE
                )
                self.send(self.px(set_alloc_id))
                raise self.wait_for_set_alloc_id() #FIXME are we done? probably not but check

    # Transitions from wait_set_alloc_id
    @ATMT.timeout(wait_set_alloc_id, 3)
    def timeout_set_alloc_id(self):
        raise self.error('Was not able to set alloc id for {}; dropping activation event for {}'
                   .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_set_alloc_id)
    def wait_for_set_alloc_id(self, pkt):
        if PAS5211MsgSetOnuAllocIdResponse in pkt:
            self.send(self.px(PAS5211MsgGetDbaMode()))
            raise self.wait_dba_mode()

    # Transitions from wait for dba mode (See Pythagoras_api.c line 344 & PMC_OFAL.c 2062)
    @ATMT.timeout(wait_dba_mode, 3)
    def timeout_wait_dba_mode(self):
        raise self.error('Did not get DBA mode for {}; dropping activation event for {}'
                   .format(self.target, hexstring(self.serial_number)))


    @ATMT.receive_condition(wait_dba_mode)
    def wait_for_dba_mode(self, pkt):
        if PAS5211MsgGetDbaModeResponse in pkt:
            if pkt.dba_mode != PON_DBA_MODE_RUNNING:
                raise self.error('DBA is not running; dropping activation event for {}'
                           .format(hexstring(self.serial_number)))

            data = pack('<LLHHBBBB', PYTHAGORAS_UPDATE_AID_SLA,
                        self.allocId, SLA_gr_bw_gros, SLA_be_bw_gros,
                        SLA_gr_bw_fine, SLA_be_bw_fine, PYTHAGORAS_DBA_DATA_COS,
                        PYTHAGORAS_DBA_STATUS_REPORT_NSR)

            send_dba_alg = PAS5211MsgSendDbaAlgorithmMsg(data=data)
            self.send(self.px(send_dba_alg))
            raise self.wait_send_dba_alg_msg()

    # Transitions from wait_send_dba_alg_msg
    @ATMT.timeout(wait_send_dba_alg_msg, 3)
    def timeout_wait_for_send_dba_alg_msg(self):
        raise self.error('Unable to set dba alg params for {}; dropping activation event for {}'
                         .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_send_dba_alg_msg)
    def wait_for_send_dba_alg_msg(self, pkt):
        if PAS5211MsgSendDbaAlgorithmMsgResponse in pkt:
            raise self.wait_dba_alg_event()

    # Transitions from wait_dba_alg_event
    @ATMT.timeout(wait_dba_alg_event, 3)
    def timeout_wait_for_send_dba_alg_event(self):
        raise self.error('DBA params ont set for {}; dropping activation event for {}'
                         .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_dba_alg_event)
    def wait_for_send_dba_alg_event(self, pkt):
        if PAS5211EventDbaAlgorithm in pkt:
            if pkt.size < PYTHAGORAS_SET_SLA_RESP_SIZE:
                raise self.error('DBA Event message too small for {}, dropping activation event for {}'
                                 .format(self.target, hexstring(self.serial_number)))

            (_, aid, _) = unpack('<LLH',pkt.data)
            if aid == self.allocId:
                # All is well moving on.
                # There is some more shit at PYTHAGORAS.c line 395 but fuck it.
                set_port_id_config = PAS5211MsgSetPortIdConfig(
                    port_id=self.port_id,
                    activate=PON_ENABLE,
                    alloc_id=self.allocId,
                    type=PON_PORT_TYPE_GEM,
                    destination=PON_PORT_DESTINATION_CNI0
                )
                self.send(self.px(set_port_id_config))
                raise self.wait_set_port_id_config()

    # Transitions from wait_set_port_id_config
    @ATMT.timeout(wait_set_port_id_config, 3)
    def timeout_wait_set_port_id_config(self):
        raise self.error('Could not set port id config for {}; dropping activation event for {}'
                         .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_set_port_id_config)
    def wait_for_set_port_id_config(self, pkt):
        if PAS5211MsgSetPortIdConfigResponse in pkt:
            get_onu_id = PAS5211MsgGetOnuIdByPortId(
                port_id=self.port_id
            )
            self.send(self.px(get_onu_id))
            raise self.wait_get_onu_id_by_port_id()

    # Transistions from wait_get_onu_id_by_port_id
    @ATMT.timeout(wait_get_onu_id_by_port_id, 3)
    def timeout_wait_get_onu_id_by_port_id(self):
        raise self.error('Could not get onu id for {}; dropping activation event for {}'
                         .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_get_onu_id_by_port_id)
    def wait_for_get_onu_id_by_port_id(self, pkt):
        if PAS5211MsgGetOnuIdByPortIdResponse in pkt:
            self.onu_id = pkt['PAS5211MsgGetOnuIdByPortIdResponse'].onu_id
            # There may be more things to do here. but traces indicate that no.
            # see PAS.c line 977 and onwards.
            set_vlan_uplink_config = PAS5211SetVlanUplinkConfiguration(
                port_id=self.port_id,
                pvid_config_enabled=PON_FALSE,
                min_cos=0,
                max_cos=7,
                de_bit=PON_DISABLE
            )
            self.send(self.px(set_vlan_uplink_config))
            raise self.wait_set_vlan_uplink_config()

    # Transitions from wait_set_vlan_uplink_config
    @ATMT.timeout(wait_set_vlan_uplink_config, 3)
    def timeout_wait_set_vlan_uplink_config(self):
        raise self.error('Could not set vlan uplink config for {}; dropping activation event for {}'
                                 .format(self.target, hexstring(self.serial_number)))

    @ATMT.receive_condition(wait_set_vlan_uplink_config)
    def wait_for_set_vlan_uplink_config(self, pkt):
        if PAS5211SetVlanUplinkConfigurationResponse in pkt:
            # YAY we made it.
            self.detect_onu()
            raise self.end()


class ActivationWatcher(BaseOltAutomaton):

    """
    States
    """

    @ATMT.state(initial=1)
    def wait_onu_activation_event(self):
        pass

    """
    Transitions
    """

    # Transitions from wait_onu_activation_event
    @ATMT.receive_condition(wait_onu_activation_event)
    def wait_for_onu_activation_event(self, pkt):
        if PAS5211EventOnuActivation in pkt:
            log.info('{} activated'.format(hexstring(pkt.serial_number)))
            onu_activation = ActivationManager(iface=self.iface, target=self.target, comm=self.comm,
                                               onu_id=pkt.onu_id, serial_number=pkt.serial_number,
                                               onu_session_id=pkt.onu_session_id,
                                               channel_id=pkt.channel_id, device=self.device)
            onu_activation.runbg()
            raise self.wait_onu_activation_event()
