#
# 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 typing import Optional, TYPE_CHECKING

from cproton import pn_condition_clear, pn_condition_set_name, pn_condition_set_description, pn_condition_info, \
    pn_condition_is_set, pn_condition_get_name, pn_condition_get_description

from ._data import Data, dat2obj

if TYPE_CHECKING:
    from ._data import PythonAMQPData


class Condition:
    """
    An AMQP Condition object. Conditions hold exception information
    pertaining to the closing of an AMQP endpoint such as a :class:`Connection`,
    :class:`Session`, or :class:`Link`. Conditions also hold similar information
    pertaining to deliveries that have reached terminal states.
    Connections, Sessions, Links, and Deliveries may all have local and
    remote conditions associated with them.

    The local condition may be modified by the local endpoint to signal
    a particular condition to the remote peer. The remote condition may
    be examined by the local endpoint to detect whatever condition the
    remote peer may be signaling. Although often conditions are used to
    indicate errors, not all conditions are errors *per/se*, e.g.
    conditions may be used to redirect a connection from one host to
    another.

    Every condition has a short symbolic name, a longer description,
    and an additional info map associated with it. The name identifies
    the formally defined condition, and the map contains additional
    information relevant to the identified condition.

    :ivar ~.name: The name of the condition.
    :ivar ~.description: A description of the condition.
    :ivar ~.info: A data object that holds the additional information associated
        with the condition. The data object may be used both to access and to
        modify the additional information associated with the condition.
    """

    def __init__(
            self,
            name: str,
            description: Optional[str] = None,
            info: Optional['PythonAMQPData'] = None
    ) -> None:
        self.name = name
        self.description = description
        self.info = info

    def __repr__(self) -> str:
        return "Condition(%s)" % ", ".join([repr(x) for x in
                                            (self.name, self.description, self.info)
                                            if x])

    def __eq__(self, o: 'Condition') -> bool:
        if not isinstance(o, Condition):
            return False
        return self.name == o.name and \
            self.description == o.description and \
            self.info == o.info


def obj2cond(obj, cond: Condition) -> None:
    pn_condition_clear(cond)
    if obj:
        pn_condition_set_name(cond, str(obj.name))
        pn_condition_set_description(cond, obj.description)
        info = Data(pn_condition_info(cond))
        if obj.info:
            info.put_object(obj.info)


def cond2obj(cond) -> Optional[Condition]:
    if pn_condition_is_set(cond):
        return Condition(pn_condition_get_name(cond),
                         pn_condition_get_description(cond),
                         dat2obj(pn_condition_info(cond)))
    else:
        return None
