/****************************************************************************
 * 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 "./mdevices_setdata.h"

#include "aqhome-cgi/modules/mdataclient.h"

#include <aqcgi/service/module.h>

#include <gwenhywfar/debug.h>
#include <gwenhywfar/timestamp.h>
#include <gwenhywfar/text.h>


/* ------------------------------------------------------------------------------------------------
 * defs and enums
 * ------------------------------------------------------------------------------------------------
 */

#define GBAS GWEN_Buffer_AppendString
#define GBAA GWEN_Buffer_AppendArgs



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

static void _setIntData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);
static void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue);



/* ------------------------------------------------------------------------------------------------
 * code
 * ------------------------------------------------------------------------------------------------
 */

void AQH_ModDevices_RunSetData(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{
  AQCGI_SERVICE *sv;
  GWEN_DB_NODE *dbPost;
  const char *sDeviceName;
  const char *sValueName;
  const AQH_VALUE *value;

  /* sample data */
  sv=AQH_ModService_GetService(m);
  dbPost=AQCGI_Request_GetDbPostBody(rq);
  sDeviceName=dbPost?GWEN_DB_GetCharValue(dbPost, "device", 0, NULL):NULL;
  sValueName=dbPost?GWEN_DB_GetCharValue(dbPost, "value", 0, NULL):NULL;
  DBG_ERROR(NULL, "Device=[%s], value=[%s]", sDeviceName?sDeviceName:"", sValueName?sValueName:"");

  value=AQH_ModDevices_GetValueForDevice(dc, sDeviceName, sValueName);
  if(value && AQH_Value_GetValueType(value)==AQH_ValueType_Actor) {
    const char *sValueName;
    const char *sValue;

    sValueName=AQH_Value_GetName(value);
    sValue=GWEN_DB_GetCharValue(dbPost, sValueName, 0, NULL);
    if (sValueName && *sValueName) {
      DBG_ERROR(NULL, "Setting value %s to %s", sValueName?sValueName:"no name", sValue?sValue:"no value");
      switch(AQH_Value_GetModality(value)) {
      case AQH_ValueModality_RGBW:      _setRgbwData(dc, value, sValue);      break;
      case AQH_ValueModality_OnOff:     _setOnOffData(dc, value, sValue);     break;
      case AQH_ValueModality_OnOffAuto: _setOnOffAutoData(dc, value, sValue); break;
      default:                          _setIntData(dc, value, sValue);       break;
      } /* switch */
    } /* if (sValueName) */
  }

  if (sDeviceName && *sDeviceName) {
    GWEN_BUFFER *pbuf;

    pbuf=GWEN_Buffer_new(0, 256, 0, 1);
    if (sValueName && *sValueName) {
      GBAS(pbuf, "Location: value.html?device=");
      GWEN_Text_EscapeToBuffer(sDeviceName, pbuf);
      GBAS(pbuf, "&value=");
      GWEN_Text_EscapeToBuffer(sValueName, pbuf);
    }
    else {
      GBAS(pbuf, "Location: values.html?device=");
      GWEN_Text_EscapeToBuffer(sDeviceName, pbuf);
    }
    AQCGI_Request_AddResponseHeaderData(rq, GWEN_Buffer_GetStart(pbuf));
    GWEN_Buffer_free(pbuf);
  }
  AQCGI_Request_SetResponseCode(rq, 303);
  AQCGI_Request_SetResponseText(rq, "See other");
}



void _setIntData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
{
  if (sValue) {
    const char *sValueSystemName;
    int intVal;
    int rv;

    sValueSystemName=AQH_Value_GetNameForSystem(value);
    if (1==sscanf(sValue, "%d", &intVal)) {
      DBG_ERROR(NULL, "Send value [%d] to %s", intVal, sValueSystemName);
      rv=AQH_DataClient_SetData(dc, value, (double) intVal);
      if (rv<0) {
	DBG_ERROR(NULL, "Error sending data: %d", rv);
      }
    }
    else {
      DBG_ERROR(NULL, "Not an integer value: [%s]", sValue);
    }
  }
}



void _setRgbwData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
{
  if (sValue) {
    const char *sValueSystemName;
    uint32_t color;
    int rv;

    sValueSystemName=AQH_Value_GetNameForSystem(value);
    color=AQH_ModDevices_ColorFromHexString(sValue);
    DBG_ERROR(NULL, "Send value [#%08x] to %s", color, sValueSystemName);
    rv=AQH_DataClient_SetData(dc, value, (double) color);
    if (rv<0) {
      DBG_ERROR(NULL, "Error sending data: %d", rv);
    }
  }
}



void _setOnOffData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
{
  if (sValue) {
    const char *sValueSystemName;
    int rv;

    sValueSystemName=AQH_Value_GetNameForSystem(value);
    if (strcasecmp(sValue, "unchanged")==0) {
      DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
    }
    else if (strcasecmp(sValue, "on")==0) {
      DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
      rv=AQH_DataClient_SetData(dc, value, 1.0);
      if (rv<0) {
        DBG_ERROR(NULL, "Error sending data: %d", rv);
      }
    }
    else if (strcasecmp(sValue, "off")==0) {
      DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
      rv=AQH_DataClient_SetData(dc, value, 0.0);
      if (rv<0) {
        DBG_ERROR(NULL, "Error sending data: %d", rv);
      }
    }
    else {
    }
  }
}



void _setOnOffAutoData(AQH_DATACLIENT *dc, const AQH_VALUE *value, const char *sValue)
{
  if (sValue) {
    const char *sValueSystemName;
    int rv;

    sValueSystemName=AQH_Value_GetNameForSystem(value);
    if (strcasecmp(sValue, "unchanged")==0) {
      DBG_ERROR(NULL, "Value %s unchanged", sValueSystemName);
    }
    else if (strcasecmp(sValue, "on")==0) {
      DBG_ERROR(NULL, "Send value 1 to %s", sValueSystemName);
      rv=AQH_DataClient_SetData(dc, value, 1.0);
      if (rv<0) {
        DBG_ERROR(NULL, "Error sending data: %d", rv);
      }
    }
    else if (strcasecmp(sValue, "off")==0) {
      DBG_ERROR(NULL, "Send value 0 to %s", sValueSystemName);
      rv=AQH_DataClient_SetData(dc, value, 0.0);
      if (rv<0) {
        DBG_ERROR(NULL, "Error sending data: %d", rv);
      }
    }
    else if (strcasecmp(sValue, "auto")==0) {
      DBG_ERROR(NULL, "Send value 2 to %s", sValueSystemName);
      rv=AQH_DataClient_SetData(dc, value, 2.0);
      if (rv<0) {
        DBG_ERROR(NULL, "Error sending data: %d", rv);
      }
    }
    else {
      DBG_ERROR(NULL, "Invalid value [%s] for %s", sValue, sValueSystemName);
    }
  }
}


