/* 
 * Copyright 2006-2008 Ondrej Jirman <ondrej.jirman@zonio.net>
 * 
 * This file is part of libxr.
 *
 * Libxr is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2 of the License, or (at your option) any
 * later version.
 *
 * Libxr is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with libxr.  If not, see <http://www.gnu.org/licenses/>.
 */

/** @file xr-client.h
 *
 * XML-RPC Client Connection API
 *
 * This API can be used to implement XML-RPC clients.
 *
 * Then basically you just create (@ref xr_client_new) connection object
 * (@ref xr_client_conn) and open connection to given URI
 * (@ref xr_client_open). Now you are free to perform XML-RPC calls
 * using code generated by @ref xdlc.
 */

#ifndef __XR_CLIENT_H__
#define __XR_CLIENT_H__

#include <openssl/ssl.h>
#include "xr-call.h"
#include "xr-http.h"
#include "xr-value-utils.h"

#define XR_CLIENT_ERROR xr_client_error_quark()

typedef enum
{
  XR_CLIENT_ERROR_MARCHALIZER,
  XR_CLIENT_ERROR_CLOSED,
  XR_CLIENT_ERROR_CONNECT,
  XR_CLIENT_ERROR_IO,
  XR_CLIENT_ERROR_FAILED
} XRClientError;

G_BEGIN_DECLS

/** Opaque data structrure that represents client connection.
 */
typedef struct _xr_client_conn xr_client_conn;

/** Create new connection object.
 *
 * @param err Error object.
 *
 * @return New connection object.
 */
xr_client_conn* xr_client_new(GError** err);

/** Get SSL context used by the client.
 *
 * This can be used for custom SSL setup.
 * 
 * @param server Server object.
 * 
 * @return SSL_CTX pointer owned by the xr_server.
 */
SSL_CTX* xr_client_get_ssl_context(xr_client_conn* conn);

/** Free connection object. This function calls @ref xr_client_close if
 * necessary.
 *
 * @param conn Connection object.
 */
void xr_client_free(xr_client_conn* conn);

/** Set transport type.
 *
 * Currently supported types are XR_CALL_XML_RPC and XR_CALL_JSON_RPC (not all
 * xr_value types).
 * 
 * @param conn Connection object.
 * @param transport Transport type.
 * 
 * @return TRUE on success, FALSE if transport is not available.
 */
gboolean xr_client_set_transport(xr_client_conn* conn, xr_call_transport transport);

/** Set HTTP header to be used in RPCs.
 *
 * This setting persists until you remove header by passing NULL value or by
 * calling xr_client_reset_http_headers().
 * 
 * @param conn Connection object.
 * @param name HTTP header name.
 * @param value HTTP header value. Value is not escaped and thus it should not span
 *   multiple lines.
 */
void xr_client_set_http_header(xr_client_conn* conn, const char* name, const char* value);

/** Remove all user defined HTTP headers.
 * 
 * @param conn Connection object.
 */
void xr_client_reset_http_headers(xr_client_conn* conn);

/** Helper function for setting HTTP headers for Basic Authorization.
 * 
 * @param conn Connection object.
 * @param username Username.
 * @param password Password.
 */
void xr_client_basic_auth(xr_client_conn* conn, const char* username, const char* password);

/** Get HTTP transport object.
 * 
 * @param conn Connection object.
 * 
 * @return HTTP transport object.
 */
xr_http* xr_client_get_http(xr_client_conn* conn);

/** Open new connection to the server.
 *
 * @param conn Connection object.
 * @param uri URI of the cleint (http[s]://host[:port]/Servlet).
 * @param err Error object.
 *
 * @return Function returns FALSE on failure and TRUE on success.
 */
gboolean xr_client_open(xr_client_conn* conn, const char* uri, GError** err);

/** Close currently open connection.
 *
 * @param conn Connection object.
 */
void xr_client_close(xr_client_conn* conn);

/** Perform XML-RPC call over connection.
 *
 * @param conn Connection object.
 * @param call Call object.
 * @param err Error object.
 *
 * @return Function returns FALSE on failure (including XML-RPC exception) and
 *   TRUE on success. XML-RPC exception have err->domain == 0.
 */
gboolean xr_client_call(xr_client_conn* conn, xr_call* call, GError** err);

GQuark xr_client_error_quark();

G_END_DECLS

#endif
