/****************************************************************************
 * 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

//#define DISABLE_DEBUGLOG


#include "./urlhandler_p.h"
#include "aqhome/http/httpservice_http.h"

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



GWEN_INHERIT_FUNCTIONS(AQH_HTTP_URLHANDLER)
GWEN_LIST_FUNCTIONS(AQH_HTTP_URLHANDLER, AQH_HttpUrlHandler)



static int _addContentHeaders(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf);
static int _addContentFooters(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf);




AQH_HTTP_URLHANDLER *AQH_HttpUrlHandler_new(AQH_SERVICE *sv)
{
  AQH_HTTP_URLHANDLER *uh;

  GWEN_NEW_OBJECT(AQH_HTTP_URLHANDLER, uh);
  GWEN_INHERIT_INIT(AQH_HTTP_URLHANDLER, uh);
  GWEN_LIST_INIT(AQH_HTTP_URLHANDLER, uh);
  uh->urlPatternList=GWEN_StringList_new();
  uh->httpService=sv;

  return uh;
}



void AQH_HttpUrlHandler_free(AQH_HTTP_URLHANDLER *uh)
{
  if (uh) {
    GWEN_LIST_FINI(AQH_HTTP_URLHANDLER, uh);
    GWEN_INHERIT_FINI(AQH_HTTP_URLHANDLER, uh);

    free(uh->folder);
    GWEN_StringList_free(uh->urlPatternList);
    GWEN_FREE_OBJECT(uh);
  }
}



AQH_SERVICE *AQH_HttpUrlHandler_GetHttpService(const AQH_HTTP_URLHANDLER *uh)
{
  return uh?uh->httpService:NULL;
}



AQH_HTTP_CONTENT *AQH_HttpUrlHandler_GetContentProvider(const AQH_HTTP_URLHANDLER *uh)
{
  return uh?uh->httpContentProvider:NULL;
}



void AQH_HttpUrlHandler_SetContentProvider(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_CONTENT *cp)
{
  if (uh)
    uh->httpContentProvider=cp;
}



void AQH_HttpUrlHandler_AddUrlPattern(AQH_HTTP_URLHANDLER *uh, const char *s)
{
  if (uh && s && *s)
    GWEN_StringList_AppendString(uh->urlPatternList, s, 0, 1);
}



const char *AQH_HttpUrlHandler_GetFolder(const AQH_HTTP_URLHANDLER *uh)
{
  return uh?uh->folder:NULL;
}



void AQH_HttpUrlHandler_SetFolder(AQH_HTTP_URLHANDLER *uh, const char *s)
{
  if (uh) {
    free(uh->folder);
    uh->folder=s?strdup(s):NULL;
  }
}



int AQH_HttpUrlHandler_UrlMatches(const AQH_HTTP_URLHANDLER *uh, const char *s)
{
  if (uh && s && *s) {
    GWEN_STRINGLISTENTRY *se;

    se=GWEN_StringList_FirstEntry(uh->urlPatternList);
    while(se) {
      const char *pattern;

      pattern=GWEN_StringListEntry_Data(se);
      if (GWEN_Text_ComparePattern(s, pattern, 0)!=-1)
        return 1;
      se=GWEN_StringListEntry_Next(se);
    }
  }
  return 0;
}



void AQH_HttpUrlHandler_SetHandleFn(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_URLHANDLER_HANDLE_FN fn)
{
  if (uh)
    uh->handleFn=fn;
}



int AQH_HttpUrlHandler_HandleMessage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
{
  if (uh && uh->handleFn)
    return uh->handleFn(uh, rq);
  return 0;
}



int AQH_HttpUrlHandler_AddContentHeaders(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf)
{
  return _addContentHeaders(uh->httpContentProvider, m, dbuf);
}



int AQH_HttpUrlHandler_AddContentFooters(AQH_HTTP_URLHANDLER *uh, int m, GWEN_BUFFER *dbuf)
{
  return _addContentFooters(uh->httpContentProvider, m, dbuf);
}



GWEN_MSG *AQH_HttpUrlHandler_CreatePageMessage(AQH_HTTP_URLHANDLER *uh,
                                               AQH_HTTP_REQUEST *rq,
                                               const char *statusTextColor, const char *statusMsg,
                                               int withHeadersAndFooters,
                                               GWEN_DB_NODE *dbValues,
                                               AQH_HTTP_URLHANDLER_WRITEPAGE_CB cb)
{
  GWEN_BUFFER *pageBuf;
  int rv;
  GWEN_MSG *msgOut=NULL;
  const char *protocol;

  protocol=AQH_HttpRequest_GetProtocol(rq);
  pageBuf=GWEN_Buffer_new(0, 256, 0, 1);
  if (withHeadersAndFooters) {
    rv=AQH_HttpUrlHandler_AddContentHeaders(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
    if (rv<0) {
      DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
      GWEN_Buffer_free(pageBuf);
      return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
    }
  }

  if (statusMsg)
    GWEN_Buffer_AppendArgs(pageBuf, "<p><font color=\"%s\">%s</font></p>", statusTextColor?statusTextColor:"black", statusMsg);
  if (cb) {
    rv=cb(uh, rq, dbValues, pageBuf);
    if (rv<0) {
      DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
      GWEN_Buffer_free(pageBuf);
      return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
    }
  }

  if (withHeadersAndFooters) {
    rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
    if (rv<0) {
      DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
      GWEN_Buffer_free(pageBuf);
      return AQH_HttpService_CreateResponseMsg(uh->httpService, 500, "Internal Error", protocol, NULL);
    }
  }

  msgOut=AQH_HttpService_CreateResponseMsg(uh->httpService, 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
  GWEN_Buffer_free(pageBuf);
  return msgOut;
}



int _addContentHeaders(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf)
{
  AQH_HTTP_CONTENT *parent;
  int rv;

  parent=AQH_HttpContent_Tree2_GetParent(c);
  if (parent) {
    rv=_addContentHeaders(parent, m, dbuf);
    if (rv<0) {
      DBG_INFO(AQH_LOGDOMAIN, "Error adding content headers for \"%s\"", AQH_HttpContent_GetName(parent));
      return rv;
    }
  }
  rv=AQH_HttpContent_AddOpeningContent(c, m, dbuf);
  if (rv<0) {
    DBG_INFO(AQH_LOGDOMAIN, "Error adding content headers for \"%s\"", AQH_HttpContent_GetName(c));
    return rv;
  }

  return 0;
}



int _addContentFooters(AQH_HTTP_CONTENT *c, int m, GWEN_BUFFER *dbuf)
{
  AQH_HTTP_CONTENT *parent;
  int rv;

  rv=AQH_HttpContent_AddClosingContent(c, m, dbuf);
  if (rv<0) {
    DBG_INFO(AQH_LOGDOMAIN, "Error adding content footers for \"%s\"", AQH_HttpContent_GetName(c));
    return rv;
  }

  parent=AQH_HttpContent_Tree2_GetParent(c);
  if (parent) {
    rv=_addContentFooters(parent, m, dbuf);
    if (rv<0) {
      DBG_INFO(AQH_LOGDOMAIN, "Error adding content footers for \"%s\"", AQH_HttpContent_GetName(parent));
      return rv;
    }
  }

  return 0;
}



