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

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


#include "./c_getdevices.h"
#include "./aqhome_data_p.h"
#include "aqhome/ipc/data/ipc_data.h"
#include "aqhome/ipc/data/msg_data_devices.h"
#include "aqhome/ipc/msg_ipc_result.h"

#include <gwenhywfar/debug.h>



/* ------------------------------------------------------------------------------------------------
 * defines
 * ------------------------------------------------------------------------------------------------
 */

#define AQHOMEDATA_DEVICESPERMSG 10



/* ------------------------------------------------------------------------------------------------
 * forward declarations
 * ------------------------------------------------------------------------------------------------
 */

static void _sendDeviceList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_DEVICE_LIST *vl, uint32_t flags);



/* ------------------------------------------------------------------------------------------------
 * implementations
 * ------------------------------------------------------------------------------------------------
 */

void AqHomeData_HandleGetDevices(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg)
{
  const AQH_DEVICE_LIST *origDeviceList;

  DBG_INFO(NULL, "HandleGetDevices");
  origDeviceList=AQH_Storage_GetDeviceList(aqh->storage);
  if (origDeviceList) {
    DBG_INFO(NULL, "Have a list of %d devices", AQH_Device_List_GetCount(origDeviceList));
    if (AQH_Device_List_GetCount(origDeviceList)<AQHOMEDATA_DEVICESPERMSG) {
      DBG_INFO(NULL, "Sending all entries in one message");
      _sendDeviceList(aqh, ep, origDeviceList, AQH_MSGDATA_DEVICES_FLAGS_LASTMSG);
    }
    else {
      AQH_DEVICE_LIST *tmpDeviceList;
      const AQH_DEVICE *v;

      DBG_INFO(NULL, "Sending entries in multiple messages");
      tmpDeviceList=AQH_Device_List_new();
      v=AQH_Device_List_First(origDeviceList);
      while(v) {
	const AQH_DEVICE *next;
	AQH_DEVICE *copyOfDevice;

	next=AQH_Device_List_Next(v);
	copyOfDevice=AQH_Device_dup(v);
	AQH_Device_List_Add(copyOfDevice, tmpDeviceList);
	if (AQH_Device_List_GetCount(tmpDeviceList)>=AQHOMEDATA_DEVICESPERMSG) {
          DBG_INFO(NULL, "Sending %d devices", AQH_Device_List_GetCount(tmpDeviceList));
	  _sendDeviceList(aqh, ep, tmpDeviceList, next?0:AQH_MSGDATA_DEVICES_FLAGS_LASTMSG);
	  AQH_Device_List_Clear(tmpDeviceList);
	}
	v=next;
      }
      if (AQH_Device_List_GetCount(tmpDeviceList)) {
        DBG_INFO(NULL, "Sending %d devices", AQH_Device_List_GetCount(tmpDeviceList));
        _sendDeviceList(aqh, ep, tmpDeviceList, AQH_MSGDATA_DEVICES_FLAGS_LASTMSG); /* send remaining */
      }
      AQH_Device_List_free(tmpDeviceList);
    }
  }
  else {
    /* empty list */
    _sendDeviceList(aqh, ep, NULL, AQH_MSGDATA_DEVICES_FLAGS_LASTMSG);
  }
}



void _sendDeviceList(AQHOME_DATA *aqh, GWEN_MSG_ENDPOINT *ep, const AQH_DEVICE_LIST *vl, uint32_t flags)
{
  GWEN_MSG *msg;

  msg=AQH_DevicesDataIpcMsg_new(AQH_MSGTYPE_IPC_DATA_GETDEVICES_RSP, flags, vl);
  GWEN_MsgEndpoint_AddSendMessage(ep, msg);
}



