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

//#define DISABLE_DEBUGLOG


#include "aqhome-cgi/service/service_p.h"

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



GWEN_INHERIT_FUNCTIONS(AQH_SERVICE);
GWEN_LIST_FUNCTIONS(AQH_SERVICE, AQH_Service);




AQH_SERVICE *AQH_Service_new(const char *baseFolder, const char *baseUrl)
{
  AQH_SERVICE *sv;

  GWEN_NEW_OBJECT(AQH_SERVICE, sv);
  GWEN_INHERIT_INIT(AQH_SERVICE, sv);
  GWEN_LIST_INIT(AQH_SERVICE, sv);

  sv->baseUrl=baseUrl?strdup(baseUrl):NULL;
  sv->baseFolder=baseFolder?strdup(baseFolder):NULL;

  if (sv->baseFolder) {
    GWEN_BUFFER *dbuf;
    uint32_t pos;

    dbuf=GWEN_Buffer_new(0, 256, 0, 1);
    GWEN_Buffer_AppendArgs(dbuf, "%s%s", sv->baseFolder, GWEN_DIR_SEPARATOR_S);
    pos=GWEN_Buffer_GetPos(dbuf);

    /* data folder */
    GWEN_Buffer_AppendString(dbuf, "data");
    sv->runtimeFolder=strdup(GWEN_Buffer_GetStart(dbuf));
    DBG_ERROR(NULL, "Runtime folder: %s", GWEN_Buffer_GetStart(dbuf));
    GWEN_Buffer_Crop(dbuf, 0, pos);

    /* cache folder */
    GWEN_Buffer_AppendString(dbuf, "cache");
    sv->cacheFolder=strdup(GWEN_Buffer_GetStart(dbuf));
    DBG_ERROR(NULL, "Cache folder: %s", GWEN_Buffer_GetStart(dbuf));
    GWEN_Buffer_Crop(dbuf, 0, pos);

    GWEN_Buffer_free(dbuf);
  }

  return sv;
}



void AQH_Service_free(AQH_SERVICE *sv)
{
  if (sv) {
    GWEN_LIST_FINI(AQH_SERVICE, sv);
    GWEN_INHERIT_FINI(AQH_SERVICE, sv);

    free(sv->baseUrl);
    free(sv->baseFolder);
    free(sv->runtimeFolder);
    free(sv->cacheFolder);
    GWEN_FREE_OBJECT(sv);
  }
}



const char *AQH_Service_GetBaseUrl(const AQH_SERVICE *sv)
{
  return sv?sv->baseUrl:NULL;
}



const char *AQH_Service_GetBaseFolder(const AQH_SERVICE *sv)
{
  return sv?sv->baseFolder:NULL;
}



const char *AQH_Service_GetRuntimeFolder(const AQH_SERVICE *sv)
{
  return sv?sv->runtimeFolder:NULL;
}



const char *AQH_Service_GetCacheFolder(const AQH_SERVICE *sv)
{
  return sv?sv->cacheFolder:NULL;
}



#if 0
AQH_MODULE *AQH_Service_GetModuleByPath(const AQH_SERVICE *sv, const char *s)
{
  if (sv && s && *s) {
    GWEN_STRINGLIST *sl;

    sl=GWEN_StringList_fromString2(s, "/", 0,
                                   GWEN_TEXT_FLAGS_DEL_QUOTES |
                                   GWEN_TEXT_FLAGS_DEL_LEADING_BLANKS |
                                   GWEN_TEXT_FLAGS_DEL_MULTIPLE_BLANKS |
                                   GWEN_TEXT_FLAGS_DEL_TRAILING_BLANKS);
    if (sl) {
      GWEN_STRINGLISTENTRY *se;
      AQH_MODULE *m;

      m=sv->rootModule;
      se=GWEN_StringList_FirstEntry(sl);
      while(se && m) {
        const char *sWantedName;

        sWantedName=GWEN_StringListEntry_Data(se);
        if (sWantedName && *sWantedName) {
          AQH_MODULE *mTemp;

          mTemp=AQH_Module_Tree2_GetFirstChild(m);
          while(mTemp) {
            const char *sModName;

            sModName=AQH_Module_GetName(mTemp);
            if (sModName && *sModName && 0==strcasecmp(sModName, sWantedName))
              break;
            mTemp=AQH_Module_Tree2_GetNext(mTemp);
          }
          if (mTemp==NULL) {
            DBG_ERROR(NULL, "Module \%s\" not found", sWantedName);
            GWEN_StringList_free(sl);
            return NULL;
          }
          m=mTemp;
        }
        else {
          DBG_ERROR(NULL, "Empty path element in \"%s\"", s);
          GWEN_StringList_free(sl);
          return NULL;
        }

        se=GWEN_StringListEntry_Next(se);
      } /* while(se && m) */
      GWEN_StringList_free(sl);
      return m;
    }
    else {
      DBG_ERROR(NULL, "Bad path \"%s\"", s);
    }
  }
  return NULL;
}
#endif



int AQH_Service_HandleRequest(AQH_SERVICE *sv, AQCGI_REQUEST *req)
{
  return (sv && sv->handleRequestFn)?(sv->handleRequestFn(sv, req)):GWEN_ERROR_NOT_IMPLEMENTED;
}



AQH_USER *AQH_Service_LoadUser(AQH_SERVICE *sv, const char *s)
{
  return (sv && sv->loadUserFn)?(sv->loadUserFn(sv, s)):NULL;
}



int AQH_Service_SaveUser(AQH_SERVICE *sv, AQH_USER *user)
{
  return (sv && sv->saveUserFn)?(sv->saveUserFn(sv, user)):GWEN_ERROR_NOT_IMPLEMENTED;
}



int AQH_Service_AddUser(AQH_SERVICE *sv, AQH_USER *user)
{
  return (sv && sv->addUserFn)?(sv->addUserFn(sv, user)):GWEN_ERROR_NOT_IMPLEMENTED;
}



int AQH_Service_DelUser(AQH_SERVICE *sv, const char *s)
{
  return (sv && sv->delUserFn)?(sv->delUserFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}



GWEN_STRINGLIST *AQH_Service_ListUsers(AQH_SERVICE *sv)
{
  return (sv && sv->listUsersFn)?(sv->listUsersFn(sv)):NULL;
}



AQH_MODULE *AQH_Service_LoadModule(AQH_SERVICE *sv, const char *s)
{
  return (sv && sv->loadModuleFn)?(sv->loadModuleFn(sv, s)):NULL;
}



int AQH_Service_SaveModule(AQH_SERVICE *sv, AQH_MODULE *module)
{
  return (sv && sv->saveModuleFn)?(sv->saveModuleFn(sv, module)):GWEN_ERROR_NOT_IMPLEMENTED;
}



int AQH_Service_AddModule(AQH_SERVICE *sv, AQH_MODULE *module)
{
  return (sv && sv->addModuleFn)?(sv->addModuleFn(sv, module)):GWEN_ERROR_NOT_IMPLEMENTED;
}



int AQH_Service_DelModule(AQH_SERVICE *sv, const char *s)
{
  return (sv && sv->delModuleFn)?(sv->delModuleFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}



GWEN_STRINGLIST *AQH_Service_ListModules(AQH_SERVICE *sv)
{
  return (sv && sv->listModulesFn)?(sv->listModulesFn(sv)):NULL;
}



AQH_SESSION* AQH_Service_LoadSession(AQH_SERVICE *sv, const char *s)
{
  return (sv && sv->loadSessionFn)?(sv->loadSessionFn(sv, s)):NULL;
}



int AQH_Service_SaveSession(AQH_SERVICE *sv, AQH_SESSION *session)
{
  return (sv && sv->saveSessionFn)?(sv->saveSessionFn(sv, session)):GWEN_ERROR_NOT_IMPLEMENTED;
}



int AQH_Service_AddSession(AQH_SERVICE *sv, AQH_SESSION *session)
{
  return (sv && sv->addSessionFn)?(sv->addSessionFn(sv, session)):GWEN_ERROR_NOT_IMPLEMENTED;
}



int AQH_Service_DelSession(AQH_SERVICE *sv, const char *s)
{
  return (sv && sv->delSessionFn)?(sv->delSessionFn(sv, s)):GWEN_ERROR_NOT_IMPLEMENTED;
}






void AQH_Service_SetHandleRequestFn(AQH_SERVICE *sv, AQH_SERVICE_HANDLEREQUEST_FN f)
{
  if (sv)
    sv->handleRequestFn=f;
}



void AQH_Service_SetLoadUserFn(AQH_SERVICE *sv, AQH_SERVICE_LOADUSER_FN f)
{
  if (sv)
    sv->loadUserFn=f;
}



void AQH_Service_SetSaveUserFn(AQH_SERVICE *sv, AQH_SERVICE_SAVEUSER_FN f)
{
  if (sv)
    sv->saveUserFn=f;
}



void AQH_Service_SetAddUserFn(AQH_SERVICE *sv, AQH_SERVICE_ADDUSER_FN f)
{
  if (sv)
    sv->addUserFn=f;
}



void AQH_Service_SetDelUserFn(AQH_SERVICE *sv, AQH_SERVICE_DELUSER_FN f)
{
  if (sv)
    sv->delUserFn=f;
}



void AQH_Service_SetListUsersFn(AQH_SERVICE *sv, AQH_SERVICE_LISTUSERS_FN f)
{
  if (sv)
    sv->listUsersFn=f;
}



void AQH_Service_SetLoadModuleFn(AQH_SERVICE *sv, AQH_SERVICE_LOADMODULE_FN f)
{
  if (sv)
    sv->loadModuleFn=f;
}



void AQH_Service_SetSaveModuleFn(AQH_SERVICE *sv, AQH_SERVICE_SAVEMODULE_FN f)
{
  if (sv)
    sv->saveModuleFn=f;
}



void AQH_Service_SetAddModuleFn(AQH_SERVICE *sv, AQH_SERVICE_ADDMODULE_FN f)
{
  if (sv)
    sv->addModuleFn=f;
}



void AQH_Service_SetDelModuleFn(AQH_SERVICE *sv, AQH_SERVICE_DELMODULE_FN f)
{
  if (sv)
    sv->delModuleFn=f;
}



void AQH_Service_SetListModulesFn(AQH_SERVICE *sv, AQH_SERVICE_LISTMODULES_FN f)
{
  if (sv)
    sv->listModulesFn=f;
}



void AQH_Service_SetLoadSessionFn(AQH_SERVICE *sv, AQH_SERVICE_LOADSESSION_FN f)
{
  if (sv)
    sv->loadSessionFn=f;
}



void AQH_Service_SetSaveSessionFn(AQH_SERVICE *sv, AQH_SERVICE_SAVESESSION_FN f)
{
  if (sv)
    sv->saveSessionFn=f;
}



void AQH_Service_SetAddSessionFn(AQH_SERVICE *sv, AQH_SERVICE_ADDSESSION_FN f)
{
  if (sv)
    sv->addSessionFn=f;
}



void AQH_Service_SetDelSessionFn(AQH_SERVICE *sv, AQH_SERVICE_DELSESSION_FN f)
{
  if (sv)
    sv->delSessionFn=f;
}



void AQH_Service_SetListSessionsFn(AQH_SERVICE *sv, AQH_SERVICE_LISTSESSIONS_FN f)
{
  if (sv)
    sv->listSessionsFn=f;
}








