#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 __future__ import absolute_import

import threading

from cproton import PN_CONNECTION_BOUND, PN_CONNECTION_FINAL, PN_CONNECTION_INIT, PN_CONNECTION_LOCAL_CLOSE, \
    PN_CONNECTION_LOCAL_OPEN, PN_CONNECTION_REMOTE_CLOSE, PN_CONNECTION_REMOTE_OPEN, PN_CONNECTION_UNBOUND, PN_DELIVERY, \
    PN_LINK_FINAL, PN_LINK_FLOW, PN_LINK_INIT, PN_LINK_LOCAL_CLOSE, PN_LINK_LOCAL_DETACH, PN_LINK_LOCAL_OPEN, \
    PN_LINK_REMOTE_CLOSE, PN_LINK_REMOTE_DETACH, PN_LINK_REMOTE_OPEN, PN_PYREF, PN_SESSION_FINAL, PN_SESSION_INIT, \
    PN_SESSION_LOCAL_CLOSE, PN_SESSION_LOCAL_OPEN, PN_SESSION_REMOTE_CLOSE, PN_SESSION_REMOTE_OPEN, PN_TIMER_TASK, \
    PN_TRANSPORT, PN_TRANSPORT_CLOSED, PN_TRANSPORT_ERROR, PN_TRANSPORT_HEAD_CLOSED, PN_TRANSPORT_TAIL_CLOSED, \
    pn_cast_pn_connection, pn_cast_pn_delivery, pn_cast_pn_link, pn_cast_pn_session, pn_cast_pn_transport, \
    pn_class_name, pn_collector, pn_collector_free, pn_collector_more, pn_collector_peek, pn_collector_pop, \
    pn_collector_put, pn_collector_release, pn_event_class, pn_event_connection, pn_event_context, pn_event_delivery, \
    pn_event_link, pn_event_session, pn_event_transport, pn_event_type, pn_event_type_name, pn_py2void, pn_void2py

from ._delivery import Delivery
from ._endpoints import Connection, Link, Session
from ._transport import Transport


class Collector:

    def __init__(self):
        self._impl = pn_collector()

    def put(self, obj, etype):
        pn_collector_put(self._impl, PN_PYREF, pn_py2void(obj), etype.number)

    def peek(self):
        return Event.wrap(pn_collector_peek(self._impl))

    def more(self):
        return pn_collector_more(self._impl)

    def pop(self):
        ev = self.peek()
        pn_collector_pop(self._impl)

    def release(self):
        pn_collector_release(self._impl)

    def __del__(self):
        pn_collector_free(self._impl)
        del self._impl


if "TypeExtender" not in globals():
    class TypeExtender:
        def __init__(self, number):
            self.number = number

        def next(self):
            try:
                return self.number
            finally:
                self.number += 1


class EventType(object):
    """
    Connects an event number to an event name, and is used
    internally by :class:`Event` to represent all known
    event types. A global list of events is maintained. An
    :class:`EventType` created with a name but no number is
    treated as an *extended* event, and is assigned an
    internal event number starting at 10000.
    """
    _lock = threading.Lock()
    _extended = TypeExtender(10000)
    TYPES = {}

    def __init__(self, name=None, number=None, method=None):
        if name is None and number is None:
            raise TypeError("extended events require a name")
        try:
            self._lock.acquire()
            if name is None:
                name = pn_event_type_name(number)

            if number is None:
                number = self._extended.next()

            if method is None:
                method = "on_%s" % name

            self.name = name
            self.number = number
            self.method = method

            self.TYPES[number] = self
        finally:
            self._lock.release()

    def __repr__(self):
        return "EventType(name=%s, number=%d)" % (self.name, self.number)

    def __str__(self):
        return self.name


def _dispatch(handler, method, *args):
    m = getattr(handler, method, None)
    if m:
        m(*args)
    elif hasattr(handler, "on_unhandled"):
        handler.on_unhandled(method, *args)


class EventBase(object):

    def __init__(self, type):
        self._type = type

    @property
    def type(self):
        """
        The type name for this event

        :type: ``str``
        """
        return self._type

    @property
    def handler(self):
        """
        The handler for this event type. Not implemented, always returns ``None``.

        :type: ``None``
        """
        return None

    def dispatch(self, handler, type=None):
        """
        Process this event by sending it to all known handlers that
        are valid for this event type.

        :param handler: Parent handler to process this event
        :type handler: :class:`Handler`
        :param type: Event type
        :type type: :class:`EventType`
        """
        type = type or self._type
        _dispatch(handler, type.method, self)
        if hasattr(handler, "handlers"):
            for h in handler.handlers:
                self.dispatch(h, type)

    def __repr__(self):
        return "%s(%r)" % (self._type, self.context)


def _core(number, method):
    return EventType(number=number, method=method)


def _internal(name):
    return EventType(name=name)


wrappers = {
    "pn_void": lambda x: pn_void2py(x),
    "pn_pyref": lambda x: pn_void2py(x),
    "pn_connection": lambda x: Connection.wrap(pn_cast_pn_connection(x)),
    "pn_session": lambda x: Session.wrap(pn_cast_pn_session(x)),
    "pn_link": lambda x: Link.wrap(pn_cast_pn_link(x)),
    "pn_delivery": lambda x: Delivery.wrap(pn_cast_pn_delivery(x)),
    "pn_transport": lambda x: Transport.wrap(pn_cast_pn_transport(x))
}


class Event(EventBase):
    """
    Notification of a state change in the protocol engine.
    """
    TIMER_TASK = _core(PN_TIMER_TASK, "on_timer_task")
    """A timer event has occurred."""


    CONNECTION_INIT = _core(PN_CONNECTION_INIT, "on_connection_init")
    """
    The connection has been created. This is the first event that
    will ever be issued for a connection. Events of this type point
    to the relevant connection.
    """

    CONNECTION_BOUND = _core(PN_CONNECTION_BOUND, "on_connection_bound")
    """
    The connection has been bound to a transport. This event is
    issued when the :meth:`Transport.bind` operation is invoked.
    """

    CONNECTION_UNBOUND = _core(PN_CONNECTION_UNBOUND, "on_connection_unbound")
    """
    The connection has been unbound from its transport. This event is
    issued when the :meth:`Transport.unbind` operation is invoked.
    """

    CONNECTION_LOCAL_OPEN = _core(PN_CONNECTION_LOCAL_OPEN, "on_connection_local_open")
    """
    The local connection endpoint has been closed. Events of this
    type point to the relevant connection.
    """

    CONNECTION_LOCAL_CLOSE = _core(PN_CONNECTION_LOCAL_CLOSE, "on_connection_local_close")
    """
    The local connection endpoint has been closed. Events of this
    type point to the relevant connection.
    """

    CONNECTION_REMOTE_OPEN = _core(PN_CONNECTION_REMOTE_OPEN, "on_connection_remote_open")
    """
    The remote endpoint has opened the connection. Events of this
    type point to the relevant connection.
    """

    CONNECTION_REMOTE_CLOSE = _core(PN_CONNECTION_REMOTE_CLOSE, "on_connection_remote_close")
    """
    The remote endpoint has closed the connection. Events of this
    type point to the relevant connection.
    """

    CONNECTION_FINAL = _core(PN_CONNECTION_FINAL, "on_connection_final")
    """
    The connection has been freed and any outstanding processing has
    been completed. This is the final event that will ever be issued
    for a connection.
    """


    SESSION_INIT = _core(PN_SESSION_INIT, "on_session_init")
    """
    The session has been created. This is the first event that will
    ever be issued for a session.
    """

    SESSION_LOCAL_OPEN = _core(PN_SESSION_LOCAL_OPEN, "on_session_local_open")
    """
    The local session endpoint has been opened. Events of this type
    point to the relevant session.
    """

    SESSION_LOCAL_CLOSE = _core(PN_SESSION_LOCAL_CLOSE, "on_session_local_close")
    """
    The local session endpoint has been closed. Events of this type
    point ot the relevant session.
    """

    SESSION_REMOTE_OPEN = _core(PN_SESSION_REMOTE_OPEN, "on_session_remote_open")
    """
    The remote endpoint has opened the session. Events of this type
    point to the relevant session.
    """

    SESSION_REMOTE_CLOSE = _core(PN_SESSION_REMOTE_CLOSE, "on_session_remote_close")
    """
    The remote endpoint has closed the session. Events of this type
    point to the relevant session.
    """

    SESSION_FINAL = _core(PN_SESSION_FINAL, "on_session_final")
    """
    The session has been freed and any outstanding processing has
    been completed. This is the final event that will ever be issued
    for a session.
    """


    LINK_INIT = _core(PN_LINK_INIT, "on_link_init")
    """
    The link has been created. This is the first event that will ever
    be issued for a link.
    """

    LINK_LOCAL_OPEN = _core(PN_LINK_LOCAL_OPEN, "on_link_local_open")
    """
    The local link endpoint has been opened. Events of this type
    point ot the relevant link.    
    """

    LINK_LOCAL_CLOSE = _core(PN_LINK_LOCAL_CLOSE, "on_link_local_close")
    """
    The local link endpoint has been closed. Events of this type
    point to the relevant link.
    """

    LINK_LOCAL_DETACH = _core(PN_LINK_LOCAL_DETACH, "on_link_local_detach")
    """
    The local link endpoint has been detached. Events of this type
    point to the relevant link.
    """

    LINK_REMOTE_OPEN = _core(PN_LINK_REMOTE_OPEN, "on_link_remote_open")
    """
    The remote endpoint has opened the link. Events of this type
    point to the relevant link.
    """

    LINK_REMOTE_CLOSE = _core(PN_LINK_REMOTE_CLOSE, "on_link_remote_close")
    """
    The remote endpoint has closed the link. Events of this type
    point to the relevant link.
    """

    LINK_REMOTE_DETACH = _core(PN_LINK_REMOTE_DETACH, "on_link_remote_detach")
    """
    The remote endpoint has detached the link. Events of this type
    point to the relevant link.
    """

    LINK_FLOW = _core(PN_LINK_FLOW, "on_link_flow")
    """
    The flow control state for a link has changed. Events of this
    type point to the relevant link.
    """

    LINK_FINAL = _core(PN_LINK_FINAL, "on_link_final")
    """
    The link has been freed and any outstanding processing has been
    completed. This is the final event that will ever be issued for a
    link. Events of this type point to the relevant link.
    """


    DELIVERY = _core(PN_DELIVERY, "on_delivery")
    """
    A delivery has been created or updated. Events of this type point
    to the relevant delivery.
    """


    TRANSPORT = _core(PN_TRANSPORT, "on_transport")
    """
    The transport has new data to read and/or write. Events of this
    type point to the relevant transport.
    """

    TRANSPORT_ERROR = _core(PN_TRANSPORT_ERROR, "on_transport_error")
    """
    Indicates that a transport error has occurred. Use :attr:`Transport.condition`
    to access the details of the error from the associated transport.
    """

    TRANSPORT_HEAD_CLOSED = _core(PN_TRANSPORT_HEAD_CLOSED, "on_transport_head_closed")
    """
    Indicates that the "head" or writing end of the transport has been closed. This
    means the transport will never produce more bytes for output to
    the network. Events of this type point to the relevant transport.
    """

    TRANSPORT_TAIL_CLOSED = _core(PN_TRANSPORT_TAIL_CLOSED, "on_transport_tail_closed")
    """
    Indicates that the "tail" of the transport has been closed. This
    means the transport will never be able to process more bytes from
    the network. Events of this type point to the relevant transport.
    """

    TRANSPORT_CLOSED = _core(PN_TRANSPORT_CLOSED, "on_transport_closed")
    """
    Indicates that the both the "head" and "tail" of the transport are
    closed. Events of this type point to the relevant transport.
    """


    # These events are now internal events in the python code
    REACTOR_INIT = _internal("reactor_init")
    """
    A reactor has been started. Events of this type point to the
    reactor.
    """

    REACTOR_QUIESCED = _internal("reactor_quiesced")
    """
    A reactor has no more events to process. Events of this type
    point to the reactor.
    """

    REACTOR_FINAL = _internal("reactor_final")
    """
    A reactor has been stopped. Events of this type point to the
    reactor.
    """


    SELECTABLE_INIT = _internal("selectable_init")
    SELECTABLE_UPDATED = _internal("selectable_updated")
    SELECTABLE_READABLE = _internal("selectable_readable")
    SELECTABLE_WRITABLE = _internal("selectable_writable")
    SELECTABLE_EXPIRED = _internal("selectable_expired")
    SELECTABLE_ERROR = _internal("selectable_error")
    SELECTABLE_FINAL = _internal("selectable_final")

    @staticmethod
    def wrap(impl):
        if impl is None:
            return None

        number = pn_event_type(impl)
        cls = pn_event_class(impl)

        if cls:
            clsname = pn_class_name(cls)
            context = wrappers[clsname](pn_event_context(impl))

            # check for an application defined ApplicationEvent and return that.  This
            # avoids an expensive wrap operation invoked by event.context
            if cls == PN_PYREF and isinstance(context, EventBase):
                return context
        else:
            clsname = None

        event = Event(impl, number, clsname, context)
        return event

    def __init__(self, impl, number, clsname, context):
        self._type = EventType.TYPES[number]
        self._clsname = clsname
        self._context = context

        # Do all this messing around to avoid duplicate wrappers
        if issubclass(type(context), Delivery):
            self._delivery = context
        else:
            self._delivery = Delivery.wrap(pn_event_delivery(impl))
        if self._delivery:
            self._link = self._delivery.link
        elif issubclass(type(context), Link):
            self._link = context
        else:
            self._link = Link.wrap(pn_event_link(impl))
        if self._link:
            self._session = self._link.session
        elif issubclass(type(context), Session):
            self._session = context
        else:
            self._session = Session.wrap(pn_event_session(impl))
        if self._session:
            self._connection = self._session.connection
        elif issubclass(type(context), Connection):
            self._connection = context
        else:
            self._connection = Connection.wrap(pn_event_connection(impl))

        if issubclass(type(context), Transport):
            self._transport = context
        else:
            self._transport = Transport.wrap(pn_event_transport(impl))

    @property
    def clazz(self):
        """
        The name of the class associated with the event context.

        :type: ``str``
        """
        return self._clsname

    @property
    def context(self):
        """
        The context object associated with the event.

        :type: Depends on the type of event, and include the following:
               - :class:`Connection`
               - :class:`Session`
               - :class:`Link`
               - :class:`Delivery`
               - :class:`Transport`
        """
        return self._context

    @property
    def handler(self):
        """
        The handler for this event. The handler is determined by looking
        at the following in order:

        - The link
        - The session
        - The connection
        - The context object with an attribute "handler"

        If none of these has a handler, then ``None`` is returned.
        """
        l = self.link
        if l:
            h = l.handler
            if h:
                return h
        s = self.session
        if s:
            h = s.handler
            if h:
                return h
        c = self.connection
        if c:
            h = c.handler
            if h:
                return h
        c = self.context
        if not c or not hasattr(c, 'handler'):
            return None
        h = c.handler
        return h

    @property
    def reactor(self):
        """
        **Deprecated** - The :class:`reactor.Container` (was reactor) associated with the event.
        """
        return self.container

    @property
    def container(self):
        """
        The :class:`reactor.Container` associated with the event.
        """
        return self._transport._reactor

    def __getattr__(self, name):
        """
        This will look for a property of the event as an attached context object of the same
        type as the property (but lowercase)
        """
        c = self.context
        # Direct type or subclass of type
        if type(c).__name__.lower() == name or name in [x.__name__.lower() for x in type(c).__bases__]:
            return c

        # If the attached object is the wrong type then see if *it* has a property of that name
        return getattr(c, name, None)

    @property
    def transport(self):
        """
        The transport associated with the event, or ``None`` if none
        is associated with it.

        :type: :class:`Transport`
        """
        return self._transport

    @property
    def connection(self):
        """
        The connection associated with the event, or ``None`` if none
        is associated with it.

        :type: :class:`Connection`
        """
        return self._connection

    @property
    def session(self):
        """
        The session associated with the event, or ``None`` if none
        is associated with it.

        :type: :class:`Session`
        """
        return self._session

    @property
    def link(self):
        """
        The link associated with the event, or ``None`` if none
        is associated with it.

        :type: :class:`Link`
        """
        return self._link

    @property
    def sender(self):
        """
        The sender link associated with the event, or ``None`` if
        none is associated with it. This is essentially an alias for
        link(), that does an additional check on the type of the
        link.

        :type: :class:`Sender` (**<-- CHECK!**)
        """
        l = self.link
        if l and l.is_sender:
            return l
        else:
            return None

    @property
    def receiver(self):
        """
        The receiver link associated with the event, or ``None`` if
        none is associated with it. This is essentially an alias for
        link(), that does an additional check on the type of the link.

        :type: :class:`Receiver` (**<-- CHECK!**)
        """
        l = self.link
        if l and l.is_receiver:
            return l
        else:
            return None

    @property
    def delivery(self):
        """
        The delivery associated with the event, or ``None`` if none
        is associated with it.

        :type: :class:`Delivery`
        """
        return self._delivery


class LazyHandlers(object):
    def __get__(self, obj, clazz):
        if obj is None:
            return self
        ret = []
        obj.__dict__['handlers'] = ret
        return ret


class Handler(object):
    """
    An abstract handler for events which supports child handlers.
    """
    handlers = LazyHandlers()

    # TODO What to do with on_error?
    def add(self, handler, on_error=None):
        """
        Add a child handler

        :param handler: A child handler
        :type handler: :class:`Handler` or one of its derivatives.
        :param on_error: Not used
        """
        self.handlers.append(handler)

    def on_unhandled(self, method, *args):
        """
        The callback for handling events which are not handled by
        any other handler.

        :param method: The name of the intended handler method.
        :type method: ``str``
        :param args: Arguments for the intended handler method.
        """
        pass
