cdef class BaseError(Exception):
    def __cinit__(self, int16_t errcode):
        self._c_errcode = errcode

    def __nonzero__(self):
        return self._c_errcode != 0

    property message:
        def __get__(self):
            if self._c_errcode in self._lookup_table:
                return self._lookup_table[self._c_errcode]
            else:
                return "Unknown error ({0})".format(self._c_errcode)

    property code:
        def __get__(self):
            return self._c_errcode

    def __str__(self):
        return '%s (%s)' % (self.message, self.code)

    def __repr__(self):
        return self.__str__()

cdef class Base:
    cdef inline int handle_error(self, int16_t ret) except -1:
        if ret == 0:
            return 0
        cdef BaseError err = self._error(ret)
        raise err

    cdef BaseError _error(self, int16_t ret): pass

cdef extern from "libimobiledevice/libimobiledevice.h":
    ctypedef enum idevice_error_t:
        IDEVICE_E_SUCCESS = 0
        IDEVICE_E_INVALID_ARG = -1
        IDEVICE_E_UNKNOWN_ERROR = -2
        IDEVICE_E_NO_DEVICE = -3
        IDEVICE_E_NOT_ENOUGH_DATA = -4
        IDEVICE_E_SSL_ERROR = -6
        IDEVICE_E_TIMEOUT = -7
    cdef enum idevice_options:
        IDEVICE_LOOKUP_USBMUX = 1 << 1
        IDEVICE_LOOKUP_NETWORK = 1 << 2
        IDEVICE_LOOKUP_PREFER_NETWORK = 1 << 3
    ctypedef void (*idevice_event_cb_t) (const_idevice_event_t event, void *user_data)
    cdef extern idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data)
    cdef extern idevice_error_t idevice_event_unsubscribe()
    idevice_error_t idevice_get_device_list(char ***devices, int *count)
    idevice_error_t idevice_device_list_free(char **devices)
    void idevice_set_debug_level(int level)
    idevice_error_t idevice_new(idevice_t *device, char *udid)
    idevice_error_t idevice_new_with_options(idevice_t *device, const char *udid, idevice_options options);
    idevice_error_t idevice_free(idevice_t device)
    idevice_error_t idevice_get_udid(idevice_t device, char** udid)
    idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle)
    idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection)
    idevice_error_t idevice_disconnect(idevice_connection_t connection)
    idevice_error_t idevice_connection_send(idevice_connection_t connection, char *data, uint32_t len, uint32_t *sent_bytes)
    idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout)
    idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes)

cdef class iDeviceError(BaseError):
    def __init__(self, *args, **kwargs):
        self._lookup_table = {
            IDEVICE_E_SUCCESS: 'Success',
            IDEVICE_E_INVALID_ARG: 'Invalid argument',
            IDEVICE_E_UNKNOWN_ERROR: 'Unknown error',
            IDEVICE_E_NO_DEVICE: 'No device',
            IDEVICE_E_NOT_ENOUGH_DATA: 'Not enough data',
            IDEVICE_E_SSL_ERROR: 'SSL Error',
            IDEVICE_E_TIMEOUT: 'Connection timeout'
        }
        BaseError.__init__(self, *args, **kwargs)

def set_debug_level(int level):
    idevice_set_debug_level(level)

cdef class iDeviceEvent:
    def __init__(self, *args, **kwargs):
        raise TypeError("iDeviceEvent cannot be instantiated")

    def __str__(self):
        return 'iDeviceEvent: %s (%s)' % (self.event == IDEVICE_DEVICE_ADD and 'Add' or 'Remove', self.udid)

    property event:
        def __get__(self):
            return self._c_event.event
    property udid:
        def __get__(self):
            return self._c_event.udid
    property conn_type:
        def __get__(self):
            return self._c_event.conn_type

cdef void idevice_event_cb(const_idevice_event_t c_event, void *user_data) with gil:
    cdef iDeviceEvent event = iDeviceEvent.__new__(iDeviceEvent)
    event._c_event = c_event
    (<object>user_data)(event)

def event_subscribe(object callback):
    cdef iDeviceError err = iDeviceError(idevice_event_subscribe(idevice_event_cb, <void*>callback))
    if err: raise err

def event_unsubscribe():
    cdef iDeviceError err = iDeviceError(idevice_event_unsubscribe())
    if err: raise err

def get_device_list():
    cdef:
        char** devices = NULL
        int count
        list result
        bytes device
        iDeviceError err = iDeviceError(idevice_get_device_list(&devices, &count))

    if err:
        if devices != NULL:
            idevice_device_list_free(devices)
        raise err

    result = []
    for i from 0 <= i < count:
        device = devices[i]
        result.append(device)

    err = iDeviceError(idevice_device_list_free(devices))
    if err: raise err
    return result

cdef class iDeviceConnection(Base):
    def __init__(self, *args, **kwargs):
        raise TypeError("iDeviceConnection cannot be instantiated.  Please use iDevice.connect()")

    cpdef bytes receive_timeout(self, uint32_t max_len, unsigned int timeout):
        cdef:
            uint32_t bytes_received
            char* c_data = <char *>malloc(max_len)
            bytes result

        try:
            self.handle_error(idevice_connection_receive_timeout(self._c_connection, c_data, max_len, &bytes_received, timeout))
            result = c_data[:bytes_received]
            return result
        except BaseError, e:
            raise
        finally:
            free(c_data)

    cpdef bytes receive(self, max_len):
        cdef:
            uint32_t bytes_received
            char* c_data = <char *>malloc(max_len)
            bytes result

        try:
            self.handle_error(idevice_connection_receive(self._c_connection, c_data, max_len, &bytes_received))
            result = c_data[:bytes_received]
            return result
        except BaseError, e:
            raise
        finally:
            free(c_data)

    cpdef disconnect(self):
        cdef idevice_error_t err
        err = idevice_disconnect(self._c_connection)
        self.handle_error(err)

    cdef BaseError _error(self, int16_t ret):
        return iDeviceError(ret)

from libc.stdlib cimport *

cdef class iDevice(Base):
    def __cinit__(self, object udid=None, *args, **kwargs):
        cdef char* c_udid = NULL
        if isinstance(udid, (str, bytes)):
            c_udid = <bytes>udid
        elif udid is not None:
            raise TypeError("iDevice's constructor takes a string or None as the udid argument")
        self.handle_error(idevice_new(&self._c_dev, c_udid))

    def __dealloc__(self):
        if self._c_dev is not NULL:
            self.handle_error(idevice_free(self._c_dev))

    cdef BaseError _error(self, int16_t ret):
        return iDeviceError(ret)

    cpdef iDeviceConnection connect(self, uint16_t port):
        cdef:
            idevice_error_t err
            idevice_connection_t c_conn = NULL
            iDeviceConnection conn
        err = idevice_connect(self._c_dev, port, &c_conn)
        try:
            self.handle_error(err)

            conn = iDeviceConnection.__new__(iDeviceConnection)
            conn._c_connection = c_conn

            return conn
        except Exception, e:
            if c_conn != NULL:
                idevice_disconnect(c_conn)

    property udid:
        def __get__(self):
            cdef:
                char* udid
                idevice_error_t err
            err = idevice_get_udid(self._c_dev, &udid)
            try:
                self.handle_error(err)
                return udid
            except Exception, e:
                if udid != NULL:
                    free(udid)
    property handle:
        def __get__(self):
            cdef uint32_t handle
            self.handle_error(idevice_get_handle(self._c_dev, &handle))
            return handle

cdef extern from *:
    ctypedef char* const_char_ptr "const char*"

cdef class BaseService(Base):
    __service_name__ = None

cdef class PropertyListService(BaseService):
    cpdef send(self, plist.Node node):
        self.handle_error(self._send(node._c_node))

    cpdef object receive(self):
        cdef:
            plist.plist_t c_node = NULL
            int16_t err
        err = self._receive(&c_node)
        try:
            self.handle_error(err)

            return plist.plist_t_to_node(c_node)
        except BaseError, e:
            if c_node != NULL:
                plist.plist_free(c_node)
            raise

    cpdef object receive_with_timeout(self, int timeout_ms):
        cdef:
            plist.plist_t c_node = NULL
            int16_t err
        err = self._receive_with_timeout(&c_node, timeout_ms)
        try:
            self.handle_error(err)

            return plist.plist_t_to_node(c_node)
        except BaseError, e:
            if c_node != NULL:
                plist.plist_free(c_node)
            raise

    cdef int16_t _send(self, plist.plist_t node):
        raise NotImplementedError("send is not implemented")

    cdef int16_t _receive(self, plist.plist_t* c_node):
        raise NotImplementedError("receive is not implemented")

    cdef int16_t _receive_with_timeout(self, plist.plist_t* c_node, int timeout_ms):
        raise NotImplementedError("receive_with_timeout is not implemented")

cdef class DeviceLinkService(PropertyListService):
    pass

include "lockdown.pxi"
include "mobilesync.pxi"
include "notification_proxy.pxi"
include "sbservices.pxi"
include "mobilebackup.pxi"
include "mobilebackup2.pxi"
include "afc.pxi"
include "file_relay.pxi"
include "screenshotr.pxi"
include "installation_proxy.pxi"
include "mobile_image_mounter.pxi"
include "webinspector.pxi"
include "heartbeat.pxi"
include "diagnostics_relay.pxi"
include "misagent.pxi"
include "house_arrest.pxi"
include "restore.pxi"
include "debugserver.pxi"
