/****************************************************************************
 * 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_valuesgraph.h"
#include "./mdevices_index.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 _writeValueToDetailedTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
static void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf);
static void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf);
static void _addGraphLink(const char *sDeviceName, const char *sValueName, const char *sPeriod, GWEN_BUFFER *dbuf, int withLink);
static void _writeDeviceInfo(const AQH_DEVICE *device, GWEN_BUFFER *dbuf);



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

void AQH_ModDevices_RunValuesAsGraph(AQCGI_MODULE *m, AQCGI_REQUEST *rq, AQCGI_SESSION *session, AQH_DATACLIENT *dc, GWEN_BUFFER *dbuf)
{
  GWEN_DB_NODE *dbQuery;
  const char *sDeviceName;

  dbQuery=AQCGI_Request_GetDbQuery(rq);
  sDeviceName=GWEN_DB_GetCharValue(dbQuery, "device", 0, NULL);
  if (!(sDeviceName && *sDeviceName))
    AQH_ModDevices_RunIndex(m, rq, session, dc, dbuf);
  else {
    AQH_DEVICE *device;

    device=AQH_DataClient_GetDeviceByName(dc, sDeviceName);
    if (device) {
      const char *sValueName;

      sValueName=GWEN_DB_GetCharValue(dbQuery, "value", 0, NULL);
      if (sValueName && *sValueName) {
        AQH_VALUE *value;

        GBAA(dbuf,"<h1>Value %s/%s</h1>\n", sDeviceName, sValueName);
        _writeDeviceInfo(device, dbuf);
        value=AQH_ModDevices_GetValueForDevice(dc, sDeviceName, sValueName);
        if (value) {
          _writeValueToDetailedTable(sDeviceName, value, dbuf);
          AQH_Value_free(value);
          AQCGI_Request_AddResponseHeaderData(rq, "Refresh: 120");
        }
      }
      else {
        AQH_VALUE_LIST *valueList;

        valueList=AQH_DataClient_GetValues(dc, sDeviceName, 0);
        if (valueList && AQH_Value_List_GetCount(valueList)) {
  
          GBAA(dbuf,"<h1>Values for Device %s</h1>\n", sDeviceName);
          _writeDeviceInfo(device, dbuf);
          _writeValueListToTable(sDeviceName, valueList, dbuf);
          GBAS(dbuf, "\n");
        }
        else {
          GBAS(dbuf,"<p>No values.</p>\n");
        }
        AQH_Value_List_free(valueList);
        AQCGI_Request_AddResponseHeaderData(rq, "Refresh: 305");
      }
      AQH_Device_free(device);
    }
  }
}


void _writeDeviceInfo(const AQH_DEVICE *device, GWEN_BUFFER *dbuf)
{
  const char *s;
  int cnt=0;

  GBAS(dbuf, "<p>");
  s=AQH_Device_GetNameForGui(device);
  if (s)
    GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
  s=AQH_Device_GetRoomName(device);
  if (s)
    GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
  s=AQH_Device_GetLocation(device);
  if (s)
    GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
  s=AQH_Device_GetDescription(device);
  if (s)
    GBAA(dbuf, "%s%s", (cnt++)?", ":"", s?s:"");
  GBAS(dbuf, "</p>");
}



void _writeValueToDetailedTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf)
{
  const char *sValueName;

  GBAS(dbuf, "<table>\n");
  sValueName=AQH_Value_GetName(value);

  GBAS(dbuf, "<tr><td>");
  _addGraphLink(sDeviceName, sValueName, "4h", dbuf, 0);
  GBAS(dbuf, "</td><td>");
  _addGraphLink(sDeviceName, sValueName, "1d", dbuf, 0);
  GBAS(dbuf, "</td></tr><tr><td>");
  _addGraphLink(sDeviceName, sValueName, "1w", dbuf, 0);
  GBAS(dbuf, "</td><td>");
  _addGraphLink(sDeviceName, sValueName, "12m", dbuf, 0);
  GBAS(dbuf, "</td></tr>\n");
}



void _writeValueListToTable(const char *sDeviceName, const AQH_VALUE_LIST *valueList, GWEN_BUFFER *dbuf)
{
  const AQH_VALUE *value;

  GBAS(dbuf, "<table>\n");


  value=AQH_Value_List_First(valueList);
  while(value) {
    if (AQH_Value_GetValueType(value)!=AQH_ValueType_Actor)
      _writeValueToTable(sDeviceName, value, dbuf);
    value=AQH_Value_List_Next(value);
  }
  GBAS(dbuf, "</table>\n");
}



void _writeValueToTable(const char *sDeviceName, const AQH_VALUE *value, GWEN_BUFFER *dbuf)
{
  const char *sValueName;
  
  /* name */
  sValueName=AQH_Value_GetName(value);

  GBAS(dbuf, "<tr><td>");
  _addGraphLink(sDeviceName, sValueName, "1d", dbuf, 1);
  GBAS(dbuf, "</td><td>");
  _addGraphLink(sDeviceName, sValueName, "1w", dbuf, 1);
  GBAS(dbuf, "</td></tr>\n");
}



void _addGraphLink(const char *sDeviceName, const char *sValueName, const char *sPeriod, GWEN_BUFFER *dbuf, int withLink)
{
  if (withLink) {
    GBAS(dbuf, "<a href=\"vgraph.html?device=");
    GWEN_Text_EscapeToBufferTolerant(sDeviceName, dbuf);
    GBAS(dbuf, "&value=");
    GWEN_Text_EscapeToBufferTolerant(sValueName, dbuf);
    GBAS(dbuf, "\">");
  }

  GBAS(dbuf, "<img src=\"graph.html?device=");
  GWEN_Text_EscapeToBufferTolerant(sDeviceName, dbuf);
  GBAS(dbuf, "&value=");
  GWEN_Text_EscapeToBufferTolerant(sValueName, dbuf);
  GBAA(dbuf, "&period=%s\"", sPeriod);
  GBAA(dbuf, " alt=\"%s\" width=\"%d\" height=\"%d\"", sValueName, AQH_MODDEVICES_GRAPH_WIDTH, AQH_MODDEVICES_GRAPH_HEIGHT);
  GBAS(dbuf, "/>");

  if (withLink) {
    GBAS(dbuf, "</a>");
  }
}



