
from __future__ import absolute_import
from __future__ import division

import functools
import sys

from dbus.exceptions import DBusException
import six


class NMDeviceNotFoundError(Exception):
    pass


class NMPropertiesNotFoundError(Exception):
    pass


class NMConnectionNotFoundError(Exception):
    pass


class NMTimeoutError(Exception):
    pass


def nmerror_dev_not_found():
    return nmerror(src_exception=DBusException,
                   dst_exception=NMDeviceNotFoundError,
                   predicate=lambda ex: ex.args[0] == 'No device found for '
                                                      'the requested iface.')


def nmerror_properties_not_found():
    return nmerror(
        src_exception=DBusException,
        dst_exception=NMPropertiesNotFoundError,
        predicate=lambda ex: ex.args[0].startswith(
            "No such interface 'org.freedesktop.DBus.Properties' on object")
    )


def nmerror(src_exception, dst_exception, predicate):
    def wrapper(func):
        @functools.wraps(func)
        def wrapped_func(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except src_exception as ex:
                if predicate(ex):
                    _, value, tb = sys.exc_info()
                    six.reraise(dst_exception, dst_exception(*value.args), tb)
                raise
        return wrapped_func
    return wrapper
