/****************************************************************************
 * This file is part of the project Gwenhywfar.
 * Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved.
 *
 * The license for this file can be found in the file COPYING which you
 * should have received along with this file.
 ****************************************************************************/

#ifndef AQH_MSGREQUEST_H
#define AQH_MSGREQUEST_H

#include <aqhome/ipc2/message.h>

#include <gwenhywfar/gwenhywfar.h>
#include <gwenhywfar/inherit.h>
#include <gwenhywfar/tree2.h>
#include <gwenhywfar/timestamp.h>


#define AQH_MSG_REQUEST_RESULT_NOT_HANDLED  0
#define AQH_MSG_REQUEST_RESULT_HANDLED      1

#define AQH_MSG_REQUEST_REASON_DONE         0
#define AQH_MSG_REQUEST_REASON_ABORTED      1
#define AQH_MSG_REQUEST_REASON_TIMEOUT      2
#define AQH_MSG_REQUEST_REASON_DISCONNECT   3

#define AQH_MSG_REQUEST_STATE_OPEN          0
#define AQH_MSG_REQUEST_STATE_DONE          1



typedef struct AQH_MSG_REQUEST AQH_MSG_REQUEST;

GWEN_INHERIT_FUNCTION_LIB_DEFS(AQH_MSG_REQUEST, AQHOME_API)
GWEN_TREE2_FUNCTION_LIB_DEFS(AQH_MSG_REQUEST, AQH_MsgRequest, AQHOME_API)

typedef int (*AQH_MSG_REQUEST_HANDLERESPONSE_FN)(AQH_MSG_REQUEST *rq, const AQH_MESSAGE *msg);
typedef void (*AQH_MSG_REQUEST_SUBREQUESTFINISHED_FN)(AQH_MSG_REQUEST *rq, AQH_MSG_REQUEST *subRq, int reason);
typedef void (*AQH_MSG_REQUEST_ABORT_FN)(AQH_MSG_REQUEST *rq, int reason);


AQHOME_API AQH_MSG_REQUEST *AQH_MsgRequest_new();
AQHOME_API void AQH_MsgRequest_free(AQH_MSG_REQUEST *rq);

AQHOME_API int AQH_MsgRequest_GetRequestType(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetRequestType(AQH_MSG_REQUEST *rq, int t);

AQHOME_API AQH_MESSAGE *AQH_MsgRequest_GetRequestMsg(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetRequestMsg(AQH_MSG_REQUEST *rq, AQH_MESSAGE *msg);

AQHOME_API AQH_OBJECT *AQH_MsgRequest_GetEndpoint(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetEndpoint(AQH_MSG_REQUEST *rq, AQH_OBJECT *ep);

AQHOME_API uint32_t AQH_MsgRequest_GetRequestMsgId(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetRequestMsgId(AQH_MSG_REQUEST *rq, uint32_t id);

AQHOME_API AQH_MESSAGE_LIST *AQH_MsgRequest_GetMsgList(const AQH_MSG_REQUEST *rq);
AQHOME_API AQH_MESSAGE *AQH_MsgRequest_GetFirstMsgFromList(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_AddMsgToList(AQH_MSG_REQUEST *rq, AQH_MESSAGE *msg);

AQHOME_API const GWEN_TIMESTAMP *AQH_MsgRequest_GetCreatedAt(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetCreatedAt(AQH_MSG_REQUEST *rq, GWEN_TIMESTAMP *ts);

AQHOME_API const GWEN_TIMESTAMP *AQH_MsgRequest_GetExpiresAt(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetExpiresAt(AQH_MSG_REQUEST *rq, GWEN_TIMESTAMP *ts);

AQHOME_API void AQH_MsgRequest_SetTimestamps(AQH_MSG_REQUEST *rq, int expiresInSecs);

AQHOME_API int AQH_MsgRequest_GetResult(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetResult(AQH_MSG_REQUEST *rq, int result);

AQHOME_API int AQH_MsgRequest_GetState(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetState(AQH_MSG_REQUEST *rq, int i);


AQHOME_API int AQH_MsgRequest_HandleResponse(AQH_MSG_REQUEST *rq, const AQH_MESSAGE *msg);
AQHOME_API void AQH_MsgRequest_SubRequestFinished(AQH_MSG_REQUEST *rq, AQH_MSG_REQUEST *subRq, int reason);
AQHOME_API void AQH_MsgRequest_Abort(AQH_MSG_REQUEST *rq, int reason);



AQHOME_API void *AQH_MsgRequest_GetPrivateData(const AQH_MSG_REQUEST *rq);
AQHOME_API void AQH_MsgRequest_SetPrivateData(AQH_MSG_REQUEST *rq, void *p);

AQHOME_API AQH_MSG_REQUEST_HANDLERESPONSE_FN AQH_MsgRequest_SetHandleResponseFn(AQH_MSG_REQUEST *rq,
                                                                                AQH_MSG_REQUEST_HANDLERESPONSE_FN fn);

AQHOME_API AQH_MSG_REQUEST_SUBREQUESTFINISHED_FN AQH_MsgRequest_SetSubRequestFinishedFn(AQH_MSG_REQUEST *rq,
                                                                                        AQH_MSG_REQUEST_SUBREQUESTFINISHED_FN f);
AQHOME_API AQH_MSG_REQUEST_ABORT_FN AQH_MsgRequest_SetAbortFn(AQH_MSG_REQUEST *rq, AQH_MSG_REQUEST_ABORT_FN f);



AQHOME_API AQH_MSG_REQUEST *AQH_MsgRequest_Tree2_FindByEndpointAndMsgId(AQH_MSG_REQUEST *rootRq, AQH_OBJECT *ep, uint32_t refMsgId);
AQHOME_API void AQH_Request_Tree2_CheckTimeouts(AQH_MSG_REQUEST *rootRq);
AQHOME_API void AQH_Request_Tree2_Cleanup(AQH_MSG_REQUEST *rootRq);
AQHOME_API int AQH_Request_Tree2_HandleIpcMsg(AQH_MSG_REQUEST *rootRq, AQH_OBJECT *srcEp, AQH_MESSAGE *recvdMsg);
AQHOME_API int AQH_Request_Tree2_HandleTtyMsg(AQH_MSG_REQUEST *rootRq, AQH_OBJECT *srcEp, AQH_MESSAGE *recvdMsg);



#endif

