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

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
from typing import Any, List, Optional, Union, TYPE_CHECKING, Callable

if TYPE_CHECKING:
    from ._reactor import Container
    from ._endpoints import Receiver, Sender
    from ._handlers import ConnectSelectable
    from ._selectable import Selectable


class Collector:

    def __init__(self) -> None:
        self._impl = pn_collector()

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

    def peek(self) -> Optional['Event']:
        return Event.wrap(pn_collector_peek(self._impl))

    def more(self) -> bool:
        return pn_collector_more(self._impl)

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

    def release(self) -> None:
        pn_collector_release(self._impl)

    def __del__(self) -> None:
        pn_collector_free(self._impl)
        del self._impl


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

        def next(self) -> int:
            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: Optional[str] = None, number: Optional[int] = None, method: Optional[str] = None) -> 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: EventType) -> None:
        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) -> str:
        return "%s(%r)" % (self._type, self.context)


def _core(number: int, method: str) -> EventType:
    return EventType(number=number, method=method)


def _internal(name: str) -> EventType:
    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) -> str:
        """
        The name of the class associated with the event context.
        """
        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) -> 'Container':
        """
        **Deprecated** - The :class:`reactor.Container` (was reactor) associated with the event.
        """
        return self.container

    @property
    def container(self) -> 'Container':
        """
        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) -> Optional[Transport]:
        """
        The transport associated with the event, or ``None`` if none
        is associated with it.
        """
        return self._transport

    @property
    def connection(self) -> Optional[Connection]:
        """
        The connection associated with the event, or ``None`` if none
        is associated with it.
        """
        return self._connection

    @property
    def session(self) -> Optional[Session]:
        """
        The session associated with the event, or ``None`` if none
        is associated with it.
        """
        return self._session

    @property
    def link(self) -> Optional[Union['Receiver', 'Sender']]:
        """
        The link associated with the event, or ``None`` if none
        is associated with it.
        """
        return self._link

    @property
    def sender(self) -> Optional['Sender']:
        """
        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.
        """
        l = self.link
        if l and l.is_sender:
            return l
        else:
            return None

    @property
    def receiver(self) -> Optional['Receiver']:
        """
        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.
        """
        l = self.link
        if l and l.is_receiver:
            return l
        else:
            return None

    @property
    def delivery(self) -> Optional[Delivery]:
        """
        The delivery associated with the event, or ``None`` if none
        is associated with it.
        """
        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: str, *args) -> None:
        """
        The callback for handling events which are not handled by
        any other handler.

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