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 = plist.native_to_plist_t(value)
        try:
            self.handle_error(lockdownd_set_value(self._c_client, domain, key, c_node))
        except BaseError, e:
            raise
        finally:
            if c_node != NULL:
                plist.plist_free(c_node)

    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)
