#ifndef _EFL_NETWORK_EO_H_
#define _EFL_NETWORK_EO_H_

#ifndef _EFL_NETWORK_EO_CLASS_TYPE
#define _EFL_NETWORK_EO_CLASS_TYPE

typedef Eo Efl_Network;

#endif

#ifndef _EFL_NETWORK_EO_TYPES
#define _EFL_NETWORK_EO_TYPES

/** Types for an ecore_con client/server object.  A correct way to set this
 * type is with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if
 * encryption is desired, and LOAD_CERT if the previously loaded certificate
 * should be used.
 *
 * @ingroup Ecore_Con
 */
typedef enum
{
  ECORE_CON_LOCAL_USER = 0, /** Socket in "~/.ecore" */
  ECORE_CON_LOCAL_SYSTEM = 1 /* 0 */, /** Socket in /tmp */
  ECORE_CON_LOCAL_ABSTRACT = 2 /* 0 */, /** Abstract socket */
  ECORE_CON_REMOTE_TCP = 3 /* 0 */, /** Remote server using TCP */
  ECORE_CON_REMOTE_MCAST = 4 /* 0 */, /** Remote multicast server */
  ECORE_CON_REMOTE_UDP = 5 /* 0 */, /** Remote server using UDP */
  ECORE_CON_REMOTE_BROADCAST = 6 /* 0 */, /** Remote broadcast using UDP */
  ECORE_CON_REMOTE_NODELAY = 7 /* 0 */, /** Remote connection sending packets
                                         * immediately */
  ECORE_CON_REMOTE_CORK = 8 /* 0 */, /** Remote connection sending data in
                                      * large chunks Note: Only available on
                                      * Linux
                                      *
                                      * @since 1.2 */
  ECORE_CON_USE_SSL2 = 16 /* 0 << 0 */, /** Use SSL2: UNSUPPORTED. */
  ECORE_CON_USE_SSL3 = 32 /* 0 << 0 */, /** Use SSL3: UNSUPPORTED. */
  ECORE_CON_USE_TLS = 64 /* 0 << 0 */, /** Use TLS */
  ECORE_CON_USE_MIXED = 96 /* Ecore.Con.Type.use_tls | Ecore.Con.Type.use_ssl3 */, /** Use both TLS and SSL3 */
  ECORE_CON_LOAD_CERT = 128 /* 0 << 0 */, /** Attempt to use the loaded
                                           * certificate */
  ECORE_CON_NO_PROXY = 256 /* 0 << 0 */, /** Disable all types of proxy on the
                                          * server Note: Only functional for
                                          * clients
                                          *
                                          * @since 1.2 */
  ECORE_CON_SOCKET_ACTIVATE = 512 /* 0 << 0 */
} Ecore_Con_Type;

typedef struct _Ecore_Con_Event_Data_Received
{
  void *data; /** The data that got sent. */
  int size; /** The length of the data sent. */
} Ecore_Con_Event_Data_Received;


#endif
/** Abstract base class for all EFL.Network classes
 *
 * @ingroup Efl_Network
 */
#define EFL_NETWORK_CLASS efl_network_class_get()

EWAPI const Eo_Class *efl_network_class_get(void);

/**
 * @brief Control the IP address of a server that has been connected to.
 *
 * The parameter is a pointer to an internal string that contains the IP
 * address of the connected server in the form "XXX.YYY.ZZZ.AAA" IP notation.
 * This string should not be modified or trusted to stay valid after deletion
 * for the svr object. If no IP is known null is returned.
 *
 * @return The IP address
 *
 * @ingroup Efl_Network
 */
EOAPI const char *efl_network_ip_get(const Eo *obj);

/**
 * @brief Check how long the object has been connected
 *
 * This function is used to find out how long a client has been connected.
 *
 * @return The total time, in seconds, that the object has been connected.
 *
 * @ingroup Efl_Network
 */
EOAPI double efl_network_uptime_get(const Eo *obj);

/**
 * @brief The port that the obj is connected to
 *
 * @return The port that obj is connected to, or -1 on error.
 *
 * @ingroup Efl_Network
 */
EOAPI int efl_network_port_get(const Eo *obj);

/**
 * @brief The port that the obj is connected to
 *
 * @param[in] port The port that obj is connected to, or -1 on error.
 *
 * @ingroup Efl_Network
 */
EOAPI void efl_network_port_set(Eo *obj, int port);

/**
 * @brief Get the fd that the server is connected to
 *
 * This function returns the fd which is used by the underlying server
 * connection. It should not be tampered with unless you REALLY know what you
 * are doing.
 *
 * @note This function is only valid for servers created with @ref
 * ecore_con_server_connect.
 *
 * @warning Seriously. Don't use this unless you know what you are doing.
 *
 * @return The fd, or -1 on failure.
 *
 * @since 1.1
 *
 * @ingroup Efl_Network
 */
EOAPI int efl_network_fd_get(const Eo *obj);

/**
 * @brief Returns whether the client is still connected
 *
 * @return Returns true if connected, false otherwise.
 *
 * @ingroup Efl_Network
 */
EOAPI Eina_Bool efl_network_connected_get(const Eo *obj);

/**
 * @brief Control the default time after which an inactive client will be
 * disconnected.
 *
 * This function is used by the server to set the default idle timeout on
 * clients. If any of the clients becomes idle for a time higher than this
 * value, it will be disconnected. A value of < 1 disables the idle timeout.
 *
 * This timeout is not affected by the one set by @ref efl_network_timeout_set.
 * A client will be disconnected whenever the client or the server timeout is
 * reached. That means, the lower timeout value  will be used for that client
 * if @ref efl_network_timeout_set is used on it.
 *
 * @return The timeout, in seconds, to disconnect after.
 *
 * @ingroup Efl_Network
 */
EOAPI double efl_network_timeout_get(const Eo *obj);

/**
 * @brief Control the default time after which an inactive client will be
 * disconnected.
 *
 * This function is used by the server to set the default idle timeout on
 * clients. If any of the clients becomes idle for a time higher than this
 * value, it will be disconnected. A value of < 1 disables the idle timeout.
 *
 * This timeout is not affected by the one set by @ref efl_network_timeout_set.
 * A client will be disconnected whenever the client or the server timeout is
 * reached. That means, the lower timeout value  will be used for that client
 * if @ref efl_network_timeout_set is used on it.
 *
 * @param[in] timeout The timeout, in seconds, to disconnect after.
 *
 * @ingroup Efl_Network
 */
EOAPI void efl_network_timeout_set(Eo *obj, double timeout);

/**
 * @brief Flushes all pending data to the given server.
 *
 * This function will block until all data is sent to the server.
 *
 * @ingroup Efl_Network
 */
EOAPI void efl_network_flush(Eo *obj);

/**
 * @brief Sends the given data to the given server.
 *
 * This function will send the given data to the server as soon as the program
 * is back to the main loop. Thus, this function returns immediately
 * (non-blocking). If the data needs to be sent now, call @ref
 * ecore_con_server_flush after this one.
 *
 * @param[in] data The given data
 * @param[in] size Length of the data, in bytes.
 *
 * @return The number of bytes sent. 0 will be returned if there is an error.
 *
 * @ingroup Efl_Network
 */
EOAPI int efl_network_send(Eo *obj, const void *data, int size);

/**
 * @brief Do an asynchronous DNS lookup.
 *
 * This function performs a DNS lookup on the hostname specified by name, then
 * calls done_cb with the result and the data given as parameter. The result
 * will be given to the done_cb as follows:
 *
 * canonname - the canonical name of the address, ip - the resolved ip address,
 * addr - a pointer to the socket address, addrlen - the length of the socket
 * address, in bytes, data - the data pointer given as parameter.
 *
 * @param[in] name IP address or server name to translate.
 * @param[in] done_cb Callback to notify when done.
 * @param[in] data User data to be given to done_cb.
 *
 * @return true if the request did not fail to be set up, false otherwise.
 *
 * @ingroup Efl_Network
 */
EOAPI Eina_Bool efl_network_lookup(const Eo *obj, const char *name, Ecore_Con_Dns_Cb done_cb, const void *data);

EOAPI extern const Eo_Event_Description _EFL_NETWORK_EVENT_DATA_RECEIVED;
EOAPI extern const Eo_Event_Description _EFL_NETWORK_EVENT_CONNECTION_UPGRADED;
EOAPI extern const Eo_Event_Description _EFL_NETWORK_EVENT_CONNECTION_ERROR;

/** Data received on connection
 *
 * @ingroup Efl_Network
 */
#define EFL_NETWORK_EVENT_DATA_RECEIVED (&(_EFL_NETWORK_EVENT_DATA_RECEIVED))

/**
 * No description
 */
#define EFL_NETWORK_EVENT_CONNECTION_UPGRADED (&(_EFL_NETWORK_EVENT_CONNECTION_UPGRADED))

/** Error received on connection
 *
 * @ingroup Efl_Network
 */
#define EFL_NETWORK_EVENT_CONNECTION_ERROR (&(_EFL_NETWORK_EVENT_CONNECTION_ERROR))

#endif
