/****************************************************************************
 * This file is part of the project AqHome.
 * AqHome (c) by 2025 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.
 ****************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "./ipc_endpoint.h"
#include "aqhome/msg/ipc/m_ipc.h"
#include "aqhome/msg/ipc/m_ipc_result.h"
#include "aqhome/msg/ipc/m_ipc_tag16.h"
#include "aqhome/msg/ipc/m_ipc_connect.h"

#include <gwenhywfar/debug.h>



int AQH_IpcEndpoint_WaitForResultMsg(AQH_OBJECT *ipcEndpoint,
                                     uint8_t protoId, uint8_t protoVer, uint16_t resultMsgCode,
                                     uint32_t refMsgId, int timeoutInSeconds)
{
  for (;;) {
    AQH_MESSAGE *msgIn;

    msgIn=AQH_IpcEndpoint_WaitForResponseMsg(ipcEndpoint, refMsgId, timeoutInSeconds);
    if (msgIn) {
      GWEN_TAG16_LIST *tagList;

      tagList=AQH_IpcMessageTag16_ParsePayload(msgIn, 0);
      if (tagList) {
        int code;

        code=AQH_IpcMessage_GetCode(msgIn);
        if (AQH_IpcMessage_GetProtoId(msgIn)==protoId &&
            AQH_IpcMessage_GetProtoVersion(msgIn)==protoVer &&
            code==resultMsgCode) {
          int result;

          result=AQH_IpcMessageResult_GetResult(tagList);
          GWEN_Tag16_List_free(tagList);
          AQH_Message_free(msgIn);
          return result;
        }
        else {
          DBG_ERROR(NULL, "Unexpected message received (%x)", code);
        }
        GWEN_Tag16_List_free(tagList);
      }
      AQH_Message_free(msgIn);
    }
    else {
      DBG_ERROR(NULL, "No matching msg received");
      return GWEN_ERROR_TIMEOUT;
    }
  } /* for */
}



AQH_MESSAGE *AQH_IpcEndpoint_WaitForResponseMsg(AQH_OBJECT *ipcEndpoint, uint32_t refMsgId, int timeoutInSeconds)
{
  time_t startTime;

  startTime=time(NULL);

  for (;;) {
    AQH_MESSAGE *msg;
    time_t now;

    while( (msg=AQH_Endpoint_GetNextMsgIn(ipcEndpoint)) ) {
      if (refMsgId==0 || refMsgId==AQH_IpcMessage_GetRefMsgId(msg))
        return msg;
      else {
        uint16_t code;

        code=AQH_IpcMessage_GetCode(msg);
        DBG_DEBUG(NULL, "Received unexpected message %d (%x), ignoring", code, code);
        AQH_Message_free(msg);
      }
    }

    now=time(NULL);
    if (now-startTime>timeoutInSeconds) {
      DBG_INFO(NULL, "Timeout");
      break;
    }
    AQH_EventLoop_Run(AQH_Object_GetEventLoop(ipcEndpoint), 500);
  }

  return NULL;
}



void AQH_IpcEndpoint_SendResponseResultToEndpoint(AQH_OBJECT *ep,
                                                  uint8_t protoId, uint8_t protoVer,uint16_t code,
                                                  uint32_t refMsgId, int result)
{
  AQH_MESSAGE *msg;

  msg=AQH_IpcMessageResult_new(protoId, protoVer, code, AQH_Endpoint_GetNextMessageId(ep), refMsgId, result, NULL);
  AQH_Endpoint_AddMsgOut(ep, msg);
}








