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

from cproton import PN_ACCEPTED, PN_MODIFIED, PN_RECEIVED, PN_REJECTED, PN_RELEASED, pn_delivery_abort, \
    pn_delivery_aborted, pn_delivery_attachments, pn_delivery_link, pn_delivery_local, pn_delivery_local_state, \
    pn_delivery_partial, pn_delivery_pending, pn_delivery_readable, pn_delivery_remote, pn_delivery_remote_state, \
    pn_delivery_settle, pn_delivery_settled, pn_delivery_tag, pn_delivery_update, pn_delivery_updated, \
    pn_delivery_writable, pn_disposition_annotations, pn_disposition_condition, pn_disposition_data, \
    pn_disposition_get_section_number, pn_disposition_get_section_offset, pn_disposition_is_failed, \
    pn_disposition_is_undeliverable, pn_disposition_set_failed, pn_disposition_set_section_number, \
    pn_disposition_set_section_offset, pn_disposition_set_undeliverable, pn_disposition_type, pn_work_next

from ._condition import cond2obj, obj2cond
from ._data import dat2obj, obj2dat
from ._wrapper import Wrapper


class NamedInt(int):
    values = {}  # type: Dict[int, str]

    def __new__(cls, i, name):
        ni = super(NamedInt, cls).__new__(cls, i)
        cls.values[i] = ni
        return ni

    def __init__(self, i, name):
        self.name = name

    def __repr__(self):
        return self.name

    def __str__(self):
        return self.name

    @classmethod
    def get(cls, i):
        return cls.values.get(i, i)


class DispositionType(NamedInt):
    values = {}


class Disposition(object):
    """
    A delivery state.

    Dispositions record the current state or final outcome of a
    transfer. Every delivery contains both a local and remote
    disposition. The local disposition holds the local state of the
    delivery, and the remote disposition holds the last known remote
    state of the delivery.
    """

    RECEIVED = DispositionType(PN_RECEIVED, "RECEIVED")
    """
    A non terminal state indicating how much (if any) message data
    has been received for a delivery.
    """    

    ACCEPTED = DispositionType(PN_ACCEPTED, "ACCEPTED")
    """
    A terminal state indicating that the delivery was successfully
    processed. Once in this state there will be no further state
    changes prior to the delivery being settled.
    """

    REJECTED = DispositionType(PN_REJECTED, "REJECTED")
    """
    A terminal state indicating that the delivery could not be
    processed due to some error condition. Once in this state
    there will be no further state changes prior to the delivery
    being settled.
    """

    RELEASED = DispositionType(PN_RELEASED, "RELEASED")
    """
    A terminal state indicating that the delivery is being
    returned to the sender. Once in this state there will be no
    further state changes prior to the delivery being settled.
    """

    MODIFIED = DispositionType(PN_MODIFIED, "MODIFIED")
    """
    A terminal state indicating that the delivery is being
    returned to the sender and should be annotated by the
    sender prior to further delivery attempts. Once in this
    state there will be no further state changes prior to the
    delivery being settled.
    """


    def __init__(self, impl, local):
        self._impl = impl
        self.local = local
        self._data = None
        self._condition = None
        self._annotations = None

    @property
    def type(self):
        """
        Get the type of this disposition object.

        Defined values are:
        
        * :const:`RECEIVED`
        * :const:`ACCEPTED`
        * :const:`REJECTED`
        * :const:`RELEASED`
        * :const:`MODIFIED`
        
        :type: ``str``
        """
        return DispositionType.get(pn_disposition_type(self._impl))

    def _get_section_number(self):
        return pn_disposition_get_section_number(self._impl)

    def _set_section_number(self, n):
        pn_disposition_set_section_number(self._impl, n)

    section_number = property(_get_section_number, _set_section_number, doc="""
        The section number associated with a disposition.

        :type: ``int``
        """)

    def _get_section_offset(self):
        return pn_disposition_get_section_offset(self._impl)

    def _set_section_offset(self, n):
        pn_disposition_set_section_offset(self._impl, n)

    section_offset = property(_get_section_offset, _set_section_offset, doc="""
        The section offset associated with a disposition.

        :type: ``int``
        """)

    def _get_failed(self):
        return pn_disposition_is_failed(self._impl)

    def _set_failed(self, b):
        pn_disposition_set_failed(self._impl, b)

    failed = property(_get_failed, _set_failed, doc="""
        The failed flag for this disposition.

        :type: ``bool``
        """)

    def _get_undeliverable(self):
        return pn_disposition_is_undeliverable(self._impl)

    def _set_undeliverable(self, b):
        pn_disposition_set_undeliverable(self._impl, b)

    undeliverable = property(_get_undeliverable, _set_undeliverable, doc="""
        The undeliverable flag for this disposition.

        :type: ``bool``
        """)

    def _get_data(self):
        if self.local:
            return self._data
        else:
            return dat2obj(pn_disposition_data(self._impl))

    def _set_data(self, obj):
        if self.local:
            self._data = obj
        else:
            raise AttributeError("data attribute is read-only")

    data = property(_get_data, _set_data, doc="""
        Access the disposition as a :class:`Data` object.

        Dispositions are an extension point in the AMQP protocol. The
        disposition interface provides setters/getters for those
        dispositions that are predefined by the specification, however
        access to the raw disposition data is provided so that other
        dispositions can be used.

        The :class:`Data` object returned by this operation is valid until
        the parent delivery is settled.

        :type: :class:`Data`
        """)

    def _get_annotations(self):
        if self.local:
            return self._annotations
        else:
            return dat2obj(pn_disposition_annotations(self._impl))

    def _set_annotations(self, obj):
        if self.local:
            self._annotations = obj
        else:
            raise AttributeError("annotations attribute is read-only")

    annotations = property(_get_annotations, _set_annotations, doc="""
        The annotations associated with a disposition.

        The :class:`Data` object retrieved by this operation may be modified
        prior to updating a delivery. When a delivery is updated, the
        annotations described by the :class:`Data` are reported to the peer
        if applicable to the current delivery state, e.g. states such as
        :const:`MODIFIED`. The :class:`Data` must be empty or contain a symbol
        keyed map.

        The :class:`Data` object returned by this operation is valid until
        the parent delivery is settled.

        :type: :class:`Data`
        """)

    def _get_condition(self):
        if self.local:
            return self._condition
        else:
            return cond2obj(pn_disposition_condition(self._impl))

    def _set_condition(self, obj):
        if self.local:
            self._condition = obj
        else:
            raise AttributeError("condition attribute is read-only")

    condition = property(_get_condition, _set_condition, doc="""
        The condition object associated with a disposition.
        
        The :class:`Condition` object retrieved by this operation may be
        modified prior to updating a delivery. When a delivery is updated,
        the condition described by the disposition is reported to the peer
        if applicable to the current delivery state, e.g. states such as
        :const:`REJECTED`.

        :type: :class:`Condition`
        """)


class Delivery(Wrapper):
    """
    Tracks and/or records the delivery of a message over a link.
    """

    RECEIVED = Disposition.RECEIVED
    """
    A non terminal state indicating how much (if any) message data
    has been received for a delivery.
    """    

    ACCEPTED = Disposition.ACCEPTED
    """
    A terminal state indicating that the delivery was successfully
    processed. Once in this state there will be no further state
    changes prior to the delivery being settled.
    """

    REJECTED = Disposition.REJECTED
    """
    A terminal state indicating that the delivery could not be
    processed due to some error condition. Once in this state
    there will be no further state changes prior to the delivery
    being settled.
    """

    RELEASED = Disposition.RELEASED
    """
    A terminal state indicating that the delivery is being
    returned to the sender. Once in this state there will be no
    further state changes prior to the delivery being settled.
    """

    MODIFIED = Disposition.MODIFIED
    """
    A terminal state indicating that the delivery is being
    returned to the sender and should be annotated by the
    sender prior to further delivery attempts. Once in this
    state there will be no further state changes prior to the
    delivery being settled.
    """


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

    def __init__(self, impl):
        Wrapper.__init__(self, impl, pn_delivery_attachments)

    def _init(self):
        self.local = Disposition(pn_delivery_local(self._impl), True)
        self.remote = Disposition(pn_delivery_remote(self._impl), False)

    @property
    def tag(self):
        """
        The identifier for the delivery.

        :type: ``bytes``
        """
        return pn_delivery_tag(self._impl)

    @property
    def writable(self):
        """
        ``True`` for an outgoing delivery to which data can now be written,
        ``False`` otherwise..

        :type: ``bool``
        """
        return pn_delivery_writable(self._impl)

    @property
    def readable(self):
        """
        ``True`` for an incoming delivery that has data to read,
        ``False`` otherwise..

        :type: ``bool``
        """
        return pn_delivery_readable(self._impl)

    @property
    def updated(self):
        """
        ``True`` if the state of the delivery has been updated
        (e.g. it has been settled and/or accepted, rejected etc),
        ``False`` otherwise.

        :type: ``bool``
        """
        return pn_delivery_updated(self._impl)

    def update(self, state):
        """
        Set the local state of the delivery e.g. :const:`ACCEPTED`,
        :const:`REJECTED`, :const:`RELEASED`.

        :param state: State of delivery
        :type state: ``int``
        """
        obj2dat(self.local._data, pn_disposition_data(self.local._impl))
        obj2dat(self.local._annotations, pn_disposition_annotations(self.local._impl))
        obj2cond(self.local._condition, pn_disposition_condition(self.local._impl))
        pn_delivery_update(self._impl, state)

    @property
    def pending(self):
        """
        The amount of pending message data for a delivery.

        :type: ``int``
        """
        return pn_delivery_pending(self._impl)

    @property
    def partial(self):
        """
        ``True`` for an incoming delivery if not all the data is
        yet available, ``False`` otherwise.

        :type: ``bool``
        """
        return pn_delivery_partial(self._impl)

    @property
    def local_state(self):
        """
        A string representation of the local state of the delivery.

        :type: ``str``
        """
        return DispositionType.get(pn_delivery_local_state(self._impl))

    @property
    def remote_state(self):
        """
        A string representation of the state of the delivery as
        indicated by the remote peer.

        :type: ``str``
        """
        return DispositionType.get(pn_delivery_remote_state(self._impl))

    @property
    def settled(self):
        """
        ``True`` if the delivery has been settled by the remote peer,
        ``False`` otherwise.

        :type: ``bool``
        """
        return pn_delivery_settled(self._impl)

    def settle(self):
        """
        Settles the delivery locally. This indicates the application
        considers the delivery complete and does not wish to receive any
        further events about it. Every delivery should be settled locally.
        """
        pn_delivery_settle(self._impl)

    @property
    def aborted(self):
        """
        ``True`` if the delivery has been aborted, ``False`` otherwise.

        :type: ``bool``
        """
        return pn_delivery_aborted(self._impl)

    def abort(self):
        """
        Aborts the delivery.  This indicates the application wishes to
        invalidate any data that may have already been sent on this delivery.
        The delivery cannot be aborted after it has been completely delivered.
        """
        pn_delivery_abort(self._impl)

    @property
    def work_next(self):
        """Deprecated: use on_message(), on_accepted(), on_rejected(),
        on_released(), and on_settled() instead.

        The next :class:`Delivery` on the connection that has pending
        operations.

        :type: :class:`Delivery`
        """
        return Delivery.wrap(pn_work_next(self._impl))

    @property
    def link(self):
        """
        The :class:`Link` on which the delivery was sent or received.

        :type: :class:`Link`
        """
        from . import _endpoints
        return _endpoints.Link.wrap(pn_delivery_link(self._impl))

    @property
    def session(self):
        """
        The :class:`Session` over which the delivery was sent or received.

        :type: :class:`Session`
        """
        return self.link.session

    @property
    def connection(self):
        """
        The :class:`Connection` over which the delivery was sent or received.

        :type: :class:`Connection`
        """
        return self.session.connection

    @property
    def transport(self):
        """
        The :class:`Transport` bound to the :class:`Connection` over which
        the delivery was sent or received.

        :type: :class:`Transport`
        """
        return self.connection.transport
