abstract Ecore.Con.Base (Eo.Base) {
   legacy_prefix: ecore_con;
   eo_prefix: ecore_con_obj;
   data: null;
   methods {
      @property ip {
         [[Control the IP address of a server that has been connected to.

           The param 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.
         ]]
         get {
             legacy: null;
         }
         values {
            ip: const(char)*; [[The IP address]]
         }
      }
      @property uptime {
         [[Check how long the object has been connected

           This function is used to find out how long a client has been
           connected for.
         ]]
         get {
             legacy: null;
         }
         values {
            uptime: double; [[The total time, in seconds, that the object has been connected.]]
         }
      }
      @property port {
         [[Return the port that the obj is connected to]]
         set {
             legacy: null;
         }
         get {
             legacy: null;
         }
         values {
            port: int; [[The The port that obj is connected to, or -1 on error.]]
         }
      }
      @property fd {
         [[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.

           @since 1.1
         ]]
         get {
             legacy: null;
         }
         values {
            fd: int; [[The fd, or -1 on failure.]]
         }
      }
      @property connected {
         [[Returns whether the client is still connected]]
         get {
             legacy: null;
         }
         values {
            connected: bool; [[Returns true if connected, false otherwise.]]
         }
      }
      @property timeout {
         [[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 the 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 @.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 @.timeout.set is used on it.
         ]]
         set {
             legacy: null;
         }
         get {
             legacy: null;
         }
         values {
            timeout: double; [[The timeout, in seconds, to disconnect after.]]
         }
      }
      flush {
         [[Flushes all pending data to the given server.

           This function will block until all data is sent to the server.
         ]]
         legacy: null;
      }
      send {
         [[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.
         ]]
         legacy: null;

         params {
            data: const(void)*; [[The given data]]
            size: int; [[Length of the data, in bytes.]]
         }
         return: int; [[The number of bytes sent. 0 will be returned if there
                        is an error.]]
      }
      lookup @class {
         [[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.
         ]]
         params {
            name: const(char)* @nonull; [[IP address or server name to translate.]]
            done_cb: Ecore_Con_Dns_Cb; [[Callback to notify when done.]]
            data: const(void)*; [[User data to be given to done_cb.]]
         }
         return: bool; [[true if the request did not fail to be set up, false otherwise.]]
      }
   }
   implements {
      @virtual .ip.get;
      @virtual .uptime.get;
      @virtual .port.set;
      @virtual .port.get;
      @virtual .fd.get;
      @virtual .connected.get;
      @virtual .timeout.set;
      @virtual .timeout.get;
      @virtual .flush;
      @virtual .send;
   }
   events {
        data,received: Ecore_Con_Event_Data_Received;
        connection,upgraded;
        connection,error: const(char) *;
   }
}

/* FIXME: Should actually be a binbuf. */
struct Ecore_Con_Event_Data_Received {
    data: void *; [[The data thet got sent.]]
    size: int; [[The length of the data sent.]]
}

/* TODO
* Add events (to all of the ecore con stuff, e.g url).
* Make server the father of the client - make sure I don't leak references.
*
* Still need to add constructor client, and most likely migrate ecore_con_eet.
*
* Split server to two classes, listener and connector (or w/e).
*
* Mark the constructing properties all around.
*/
