/*
 * libsyncml - A syncml protocol implementation
 * Copyright (C) 2005  Armin Bauer <armin.bauer@opensync.org>
 * Copyright (C) 2007-2009  Michael Bell <michael.bell@opensync.org>
 *
 * This library 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.1 of the License, or (at your option) any later version.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 */

#ifndef _SML_SESSION_H_
#define _SML_SESSION_H_

typedef struct SmlSession       SmlSession;
typedef struct SmlPendingStatus SmlPendingStatus;

typedef enum SmlSessionEventType {
	SML_SESSION_EVENT_ERROR,
	SML_SESSION_EVENT_COMMAND_START,
	SML_SESSION_EVENT_CHILD_COMMAND,
	SML_SESSION_EVENT_HEADER_REPLY,
	SML_SESSION_EVENT_FINAL,
	SML_SESSION_EVENT_END,
	SML_SESSION_EVENT_FLUSH,
	SML_SESSION_EVENT_COMMAND_END,
	SML_SESSION_EVENT_RESPONSE_URI,
	SML_SESSION_EVENT_ESTABLISHED
} SmlSessionEventType;

#include "sml_command.h"
#include "sml_transport.h"

typedef void (* SmlSessionEventCallback) (SmlSession *session, SmlSessionEventType type, SmlCommand *command, SmlCommand *parent, SmlStatus *reply, const GError *error, void *userdata);
typedef void (* SmlSessionDataCallback)  (SmlSession *session, SmlTransportData *data, void *userdata);
typedef void (* SmlStatusReplyCb)        (SmlSession *session, SmlStatus *status, void *userdata);

#include "sml_parse.h"

/* Session Management */
SmlSession* smlSessionNew              (SmlSessionType sessionType, SmlMimeType mimetype, SmlProtocolVersion version, SmlProtocolType protocol, SmlLocation *target, SmlLocation *source, const gsize sessionID, gsize messageID, GError **error);
SmlSession* smlSessionRef              (SmlSession *session);
void        smlSessionUnref            (SmlSession *session);
void        smlSessionSetEventCallback (SmlSession *session, SmlSessionEventCallback callback, void *userdata);
void        smlSessionSetDataCallback  (SmlSession *session, SmlSessionDataCallback callback, void *userdata);

/* Session Control */
gboolean smlSessionFlush              (SmlSession *session, gboolean final, GError **error);
gboolean smlSessionEnd                (SmlSession *session, GError **error);
void     smlSessionUseStringTable     (SmlSession *session, gboolean useStringtable);
void     smlSessionUseOnlyReplace     (SmlSession *session, gboolean onlyReplace);
void     smlSessionUseNumberOfChanges (SmlSession *session, gboolean support);
void     smlSessionUseLargeObjects    (SmlSession *session, gboolean support);
void     smlSessionSetEstablished     (SmlSession *session, gboolean estabished);
gboolean smlSessionGetEstablished     (SmlSession *session);

void  smlSessionSetRemoteMaxMsgSize   (SmlSession *session, gsize size);
void  smlSessionSetLocalMaxMsgSize    (SmlSession *session, gsize size);
gsize smlSessionGetRemoteMaxMsgSize   (SmlSession *session);
gsize smlSessionGetLocalMaxMsgSize    (SmlSession *session);
void  smlSessionSetLocalMaxMsgChanges (SmlSession *session, gsize size);

void  smlSessionSetLocalMaxObjSize  (SmlSession *session, gsize limit);
void  smlSessionSetRemoteMaxObjSize (SmlSession *session, gsize limit);
gsize smlSessionGetLocalMaxObjSize  (SmlSession *session);
gsize smlSessionGetRemoteMaxObjSize (SmlSession *session);

gsize              smlSessionGetSessionID  (SmlSession *session);
void               smlSessionSetSessionID  (SmlSession *session, gsize sessionID);
SmlProtocolVersion smlSessionGetVersion    (SmlSession *session);
SmlSessionType     smlSessionGetType       (SmlSession *session);
void               smlSessionSetType       (SmlSession *session, SmlSessionType type);
void               smlSessionDispatchEvent (SmlSession *session, SmlSessionEventType type, SmlCommand *cmd, SmlCommand *parent, SmlStatus *headerreply, const GError *error);
SmlLocation*       smlSessionGetSource     (SmlSession *session);
void               smlSessionSetSource     (SmlSession *session, SmlLocation *source);
SmlLocation*       smlSessionGetTarget     (SmlSession *session);
/* This function MUST NOT be used for servers.
 * This function is only used to set the credentials for a client.
 */
void     smlSessionRegisterCred    (SmlSession *session, SmlCred *cred);
SmlChal* smlSessionGetChal         (SmlSession *session);
void     smlSessionSetChal         (SmlSession *session, SmlChal *chal);
gboolean smlSessionGetEnd          (SmlSession *session);
void     smlSessionSetEnd          (SmlSession *session, gboolean end);
gboolean smlSessionGetAuthenticate (SmlSession *session);
void     smlSessionSetAuthenticate (SmlSession *session, gboolean authenticate);

/* Session Data input */
gboolean smlSessionReceiveHeader (SmlSession *session, SmlHeader *header, GError **error);
gboolean smlSessionReceiveBody   (SmlSession *session, SmlParser *parser, GError **error);

/* Session Command input */
gboolean smlSessionSendCommand  (SmlSession *session, SmlCommand *cmd, SmlCommand *parent, SmlStatusReplyCb callback, void *userdata, GError **error);
gboolean smlSessionStartCommand (SmlSession *session, SmlCommand *cmd, SmlCommand *parent, SmlStatusReplyCb callback, void *userdata, GError **error);
gboolean smlSessionEndCommand   (SmlSession *session, SmlCommand *parent, GError **error);
gboolean smlSessionSendReply    (SmlSession *session, SmlStatus *status, GError **error);

gboolean smlSessionCheck    (SmlSession *session);
void     smlSessionDispatch (SmlSession *session);

gboolean smlSessionTryLock (SmlSession *session);
void     smlSessionLock    (SmlSession *session);
void     smlSessionUnlock  (SmlSession *session);

void     smlSessionRestoreTargetURI (SmlSession *session);
gboolean smlSessionSetResponseURI   (SmlSession *session, const gchar *responseURI, GError **error);

gsize smlSessionGetLastRecvMsgID (SmlSession *session);

#endif //_SML_SESSION_H_
