cdef extern from "libimobiledevice/lockdown.h":
    ctypedef enum lockdownd_error_t:
        LOCKDOWN_E_SUCCESS
        LOCKDOWN_E_INVALID_ARG
        LOCKDOWN_E_INVALID_CONF
        LOCKDOWN_E_PLIST_ERROR
        LOCKDOWN_E_PAIRING_FAILED
        LOCKDOWN_E_SSL_ERROR
        LOCKDOWN_E_DICT_ERROR
        LOCKDOWN_E_RECEIVE_TIMEOUT
        LOCKDOWN_E_SET_VALUE_PROHIBITED
        LOCKDOWN_E_GET_VALUE_PROHIBITED
        LOCKDOWN_E_MUX_ERROR
        LOCKDOWN_E_NO_RUNNING_SESSION
        LOCKDOWN_E_INVALID_RESPONSE
        LOCKDOWN_E_MISSING_KEY
        LOCKDOWN_E_MISSING_VALUE
        LOCKDOWN_E_GET_PROHIBITED
        LOCKDOWN_E_SET_PROHIBITED
        LOCKDOWN_E_REMOVE_PROHIBITED
        LOCKDOWN_E_IMMUTABLE_VALUE
        LOCKDOWN_E_PASSWORD_PROTECTED
        LOCKDOWN_E_USER_DENIED_PAIRING
        LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING
        LOCKDOWN_E_MISSING_HOST_ID
        LOCKDOWN_E_INVALID_HOST_ID
        LOCKDOWN_E_SESSION_ACTIVE
        LOCKDOWN_E_SESSION_INACTIVE
        LOCKDOWN_E_MISSING_SESSION_ID
        LOCKDOWN_E_INVALID_SESSION_ID
        LOCKDOWN_E_MISSING_SERVICE
        LOCKDOWN_E_INVALID_SERVICE
        LOCKDOWN_E_SERVICE_LIMIT
        LOCKDOWN_E_MISSING_PAIR_RECORD
        LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED
        LOCKDOWN_E_INVALID_PAIR_RECORD
        LOCKDOWN_E_INVALID_ACTIVATION_RECORD
        LOCKDOWN_E_MISSING_ACTIVATION_RECORD
        LOCKDOWN_E_SERVICE_PROHIBITED
        LOCKDOWN_E_ESCROW_LOCKED
        LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION
        LOCKDOWN_E_FMIP_PROTECTED
        LOCKDOWN_E_MC_PROTECTED
        LOCKDOWN_E_MC_CHALLENGE_REQUIRED
        LOCKDOWN_E_UNKNOWN_ERROR

    lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, char *label)
    lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, char *label)
    lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)

    lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **tp)
    lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t *value)
    lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, char *domain, char *key, plist.plist_t value)
    lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, char *domain, char *key)
    lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, char *identifier, lockdownd_service_descriptor_t *service)
    lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, char *host_id, char **session_id, int *ssl_enabled)
    lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, char *session_id)
    lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist.plist_t plist)
    lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist.plist_t *plist)
    lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
    lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
    lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record)
    lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist.plist_t activation_record)
    lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client)
    lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client)
    lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)
    lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count)
    lockdownd_error_t lockdownd_data_classes_free(char **classes)
    lockdownd_error_t lockdownd_service_descriptor_free(lockdownd_service_descriptor_t service)

cdef class LockdownError(BaseError):
    def __init__(self, *args, **kwargs):
        self._lookup_table = {
            LOCKDOWN_E_SUCCESS: "Success",
            LOCKDOWN_E_INVALID_ARG: "Invalid argument",
            LOCKDOWN_E_INVALID_CONF: "Invalid configuration",
            LOCKDOWN_E_PLIST_ERROR: "Property list error",
            LOCKDOWN_E_PAIRING_FAILED: "Pairing failed",
            LOCKDOWN_E_SSL_ERROR: "SSL error",
            LOCKDOWN_E_DICT_ERROR: "Dictionary error",
            LOCKDOWN_E_RECEIVE_TIMEOUT: "Receive timeout",
            LOCKDOWN_E_MUX_ERROR: "Mux Protocol Error",
            LOCKDOWN_E_NO_RUNNING_SESSION: "No running session",
            LOCKDOWN_E_INVALID_RESPONSE: "Invalid response",
            LOCKDOWN_E_MISSING_KEY: "Missing key",
            LOCKDOWN_E_MISSING_VALUE: "Missing value",
            LOCKDOWN_E_GET_PROHIBITED: "Get value prohibited",
            LOCKDOWN_E_SET_PROHIBITED: "Set value prohibited",
            LOCKDOWN_E_REMOVE_PROHIBITED: "Remove value prohibited",
            LOCKDOWN_E_IMMUTABLE_VALUE: "Immutable value",
            LOCKDOWN_E_PASSWORD_PROTECTED: "Password protected",
            LOCKDOWN_E_USER_DENIED_PAIRING: "User denied pairing",
            LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING: "Pairing dialog response pending",
            LOCKDOWN_E_MISSING_HOST_ID: "Missing host ID",
            LOCKDOWN_E_INVALID_HOST_ID: "Invalid host ID",
            LOCKDOWN_E_SESSION_ACTIVE: "Session active",
            LOCKDOWN_E_SESSION_INACTIVE: "Session inactive",
            LOCKDOWN_E_MISSING_SESSION_ID: "Missing session ID",
            LOCKDOWN_E_INVALID_SESSION_ID: "Invalid session ID",
            LOCKDOWN_E_MISSING_SERVICE: "Missing service",
            LOCKDOWN_E_INVALID_SERVICE: "Invalid service",
            LOCKDOWN_E_SERVICE_LIMIT: "Service limit reached",
            LOCKDOWN_E_MISSING_PAIR_RECORD: "Missing pair record",
            LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED: "Saving pair record failed",
            LOCKDOWN_E_INVALID_PAIR_RECORD: "Invalid pair record",
            LOCKDOWN_E_INVALID_ACTIVATION_RECORD: "Invalid activation record",
            LOCKDOWN_E_MISSING_ACTIVATION_RECORD: "Missing activation record",
            LOCKDOWN_E_SERVICE_PROHIBITED: "Service prohibited",
            LOCKDOWN_E_ESCROW_LOCKED: "Escrow locked",
            LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION: "Pairing prohibited over this connection",
            LOCKDOWN_E_FMIP_PROTECTED: "Find My iPhone/iPod/iPad protected",
            LOCKDOWN_E_MC_PROTECTED: "MC protected",
            LOCKDOWN_E_MC_CHALLENGE_REQUIRED: "MC challenge required",
            LOCKDOWN_E_UNKNOWN_ERROR: "Unknown error"
        }
        BaseError.__init__(self, *args, **kwargs)

cdef class LockdownPairRecord:
    #def __cinit__(self, bytes device_certificate, bytes host_certificate, bytes host_id, bytes root_certificate, *args, **kwargs):
    property device_certificate:
        def __get__(self):
            cdef bytes result = self._c_record.device_certificate
            return result
    property host_certificate:
        def __get__(self):
            cdef bytes result = self._c_record.host_certificate
            return result
    property host_id:
        def __get__(self):
            cdef bytes result = self._c_record.host_id
            return result
    property root_certificate:
        def __get__(self):
            cdef bytes result = self._c_record.root_certificate
            return result

cdef class LockdownServiceDescriptor(Base):
    #def __cinit__(self, uint16_t port, uint8_t ssl_enabled, *args, **kwargs):
    def __dealloc__(self):
        cdef lockdownd_error_t err
        if self._c_service_descriptor is not NULL:
            err = lockdownd_service_descriptor_free(self._c_service_descriptor)
            self._c_service_descriptor = NULL
            self.handle_error(err)
    property port:
        def __get__(self):
            return self._c_service_descriptor.port
    property ssl_enabled:
        def __get__(self):
            return self._c_service_descriptor.ssl_enabled

cdef class LockdownClient(PropertyListService):
    def __cinit__(self, iDevice device not None, bytes label=b'', bint handshake=True, *args, **kwargs):
        cdef:
            lockdownd_error_t err
            char* c_label = NULL
        if label:
            c_label = label
        if handshake:
            err = lockdownd_client_new_with_handshake(device._c_dev, &self._c_client, c_label)
        else:
            err = lockdownd_client_new(device._c_dev, &self._c_client, c_label)
        self.handle_error(err)

        self.device = device

    def __dealloc__(self):
        cdef lockdownd_error_t err
        if self._c_client is not NULL:
            err = lockdownd_client_free(self._c_client)
            self.handle_error(err)

    cpdef bytes query_type(self):
        cdef:
            lockdownd_error_t err
            char* c_type = NULL
            bytes result
        err = lockdownd_query_type(self._c_client, &c_type)
        try:
            self.handle_error(err)
            result = c_type

            return result
        except BaseError, e:
            raise
        finally:
            if c_type != NULL:
                free(c_type)

    cpdef plist.Node get_value(self, bytes domain=None, bytes key=None):
        cdef:
            lockdownd_error_t err
            plist.plist_t c_node = NULL
            char* c_domain = NULL
            char* c_key = NULL
        if domain is not None:
            c_domain = domain
        if key is not None:
            c_key = key

        err = lockdownd_get_value(self._c_client, c_domain, c_key, &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 set_value(self, bytes domain, bytes key, object value):
        cdef: 
            plist.plist_t c_node = NULL
            char* c_domain = NULL
            char* c_key = NULL

        c_node = plist.native_to_plist_t(value)
        if domain is not None:
            c_domain = domain
        if key is not None:
            c_key = key
        try:
            self.handle_error(lockdownd_set_value(self._c_client, c_domain, c_key, c_node))
        except BaseError, e:
            raise
        finally:
            if c_node != NULL:
                c_node = NULL

    cpdef remove_value(self, bytes domain, bytes key):
        self.handle_error(lockdownd_remove_value(self._c_client, domain, key))

    cpdef object start_service(self, object service):
        cdef:
            char* c_service_name = NULL
            lockdownd_service_descriptor_t c_descriptor = NULL
            LockdownServiceDescriptor result

        if issubclass(service, BaseService) and \
            service.__service_name__ is not None \
            and isinstance(service.__service_name__, (str, bytes)):
            c_service_name_str = service.__service_name__.encode('utf-8')
        elif isinstance(service, (str, bytes)):
            c_service_name_str = service.encode('utf-8')
        else:
            raise TypeError("LockdownClient.start_service() takes a BaseService or string as its first argument")
        c_service_name = c_service_name_str

        try:
            self.handle_error(lockdownd_start_service(self._c_client, c_service_name, &c_descriptor))

            result = LockdownServiceDescriptor.__new__(LockdownServiceDescriptor)
            result._c_service_descriptor = c_descriptor

            return result
        except BaseError, e:
            raise

    cpdef object get_service_client(self, object service_class):
        cdef:
            LockdownServiceDescriptor descriptor

        if not hasattr(service_class, '__service_name__') and \
            not service_class.__service_name__ is not None \
            and not isinstance(service_class.__service_name__, (str, bytes)):
            raise TypeError("LockdownClient.get_service_client() takes a BaseService as its first argument")

        descriptor = self.start_service(service_class)
        return service_class(self.device, descriptor)

    cpdef tuple start_session(self, bytes host_id):
        cdef:
            lockdownd_error_t err
            char* c_session_id = NULL
            bint ssl_enabled
            bytes session_id
        err = lockdownd_start_session(self._c_client, host_id, &c_session_id, <int *>&ssl_enabled)
        try:
            self.handle_error(err)

            session_id = c_session_id
            return (session_id, ssl_enabled)
        except BaseError, e:
            raise
        finally:
            if c_session_id != NULL:
                free(c_session_id)

    cpdef stop_session(self, bytes session_id):
        self.handle_error(lockdownd_stop_session(self._c_client, session_id))

    cpdef pair(self, object pair_record=None):
        cdef lockdownd_pair_record_t c_pair_record = NULL
        if pair_record is not None:
            c_pair_record = (<LockdownPairRecord>pair_record)._c_record
        self.handle_error(lockdownd_pair(self._c_client, c_pair_record))

    cpdef validate_pair(self, object pair_record=None):
        cdef lockdownd_pair_record_t c_pair_record = NULL
        if pair_record is not None:
            c_pair_record = (<LockdownPairRecord>pair_record)._c_record
        self.handle_error(lockdownd_validate_pair(self._c_client, c_pair_record))

    cpdef unpair(self, object pair_record=None):
        cdef lockdownd_pair_record_t c_pair_record = NULL
        if pair_record is not None:
            c_pair_record = (<LockdownPairRecord>pair_record)._c_record
        self.handle_error(lockdownd_unpair(self._c_client, c_pair_record))

    cpdef activate(self, plist.Node activation_record):
        self.handle_error(lockdownd_activate(self._c_client, activation_record._c_node))

    cpdef deactivate(self):
        self.handle_error(lockdownd_deactivate(self._c_client))

    cpdef enter_recovery(self):
        self.handle_error(lockdownd_enter_recovery(self._c_client))

    cpdef goodbye(self):
        self.handle_error(lockdownd_goodbye(self._c_client))

    cpdef list get_sync_data_classes(self):
        cdef:
            char **classes = NULL
            int count = 0
            list result = []
            bytes data_class

        try:
            self.handle_error(lockdownd_get_sync_data_classes(self._c_client, &classes, &count))

            for i from 0 <= i < count:
                data_class = classes[i]
                result.append(data_class)

            return result
        except Exception, e:
            raise
        finally:
            if classes != NULL:
                lockdownd_data_classes_free(classes)

    cdef inline int16_t _send(self, plist.plist_t node):
        return lockdownd_send(self._c_client, node)

    cdef inline int16_t _receive(self, plist.plist_t* node):
        return lockdownd_receive(self._c_client, node)

    cdef inline BaseError _error(self, int16_t ret):
        return LockdownError(ret)
