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

/* This file is included by "path.c" */


#include <gwenhywfar/testframework.h>
#include "path-t.h"


#ifdef AQHOME_ENABLE_TESTCODE


typedef struct PATH_TEST_ENTRY PATH_TEST_ENTRY;
struct PATH_TEST_ENTRY {
  const char *element;
  int index;
  uint32_t flags;
};



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

static int GWENHYWFAR_CB test1(GWEN_TEST_MODULE *mod);
static int GWENHYWFAR_CB test2(GWEN_TEST_MODULE *mod);
static int GWENHYWFAR_CB test3(GWEN_TEST_MODULE *mod);
static int GWENHYWFAR_CB test4(GWEN_TEST_MODULE *mod);


static void *_cbTestElement(const char *element, void *data, int idx, uint32_t flags);



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

int AQH_Path_AddTests(GWEN_TEST_MODULE *mod)
{
  GWEN_TEST_MODULE *newMod;

  newMod=GWEN_Test_Module_AddModule(mod, "AQH_Path", NULL);

  GWEN_Test_Module_AddTest(newMod, "test 1: path with index", test1, NULL);
  GWEN_Test_Module_AddTest(newMod, "test 2: path without index", test2, NULL);
  GWEN_Test_Module_AddTest(newMod, "test 3: path with backspace escape", test3, NULL);
  GWEN_Test_Module_AddTest(newMod, "test 4: path with index and different delimiter", test4, NULL);

  return 0;
}



int test1(GWEN_UNUSED GWEN_TEST_MODULE *mod)
{
  static char path[]="/test1/test2[3]/test3[2]";
  static PATH_TEST_ENTRY expected[]={
    {"test1", 0, AQH_PATH_FLAGS_PARSEIDX},
    {"test2", 3, AQH_PATH_FLAGS_PARSEIDX},
    {"test3", 2, AQH_PATH_FLAGS_PARSEIDX | AQH_PATH_FLAGS_LAST},
    {NULL,    0, 0}
  };

  if (AQH_Path_Handle(path, expected, AQH_PATH_FLAGS_PARSEIDX, "/", _cbTestElement)==NULL) {
    DBG_ERROR(NULL, "Error handling patch \"%s\"", path);
    return GWEN_ERROR_GENERIC;
  }

  return 0;
}



int test2(GWEN_UNUSED GWEN_TEST_MODULE *mod)
{
  static char path[]="/test1/test2[3]/test3[2]";
  static PATH_TEST_ENTRY expected[]={
    {"test1",    0, 0},
    {"test2[3]", 0, 0},
    {"test3[2]", 0, AQH_PATH_FLAGS_LAST},
    {NULL,       0, 0}
  };

  if (AQH_Path_Handle(path, expected, 0, "/", _cbTestElement)==NULL) {
    DBG_ERROR(NULL, "Error handling patch \"%s\"", path);
    return GWEN_ERROR_GENERIC;
  }

  return 0;
}



int test3(GWEN_UNUSED GWEN_TEST_MODULE *mod)
{
  static char path[]="/test1\\/test2[3]/test3[2]/test4[1]";
  static PATH_TEST_ENTRY expected[]={
    {"test1/test2", 3, AQH_PATH_FLAGS_PARSEIDX},
    {"test3",       2, AQH_PATH_FLAGS_PARSEIDX},
    {"test4",       1, AQH_PATH_FLAGS_PARSEIDX | AQH_PATH_FLAGS_LAST},
    {NULL,          0, 0}
  };

  if (AQH_Path_Handle(path, expected, AQH_PATH_FLAGS_PARSEIDX, "/", _cbTestElement)==NULL) {
    DBG_ERROR(NULL, "Error handling patch \"%s\"", path);
    return GWEN_ERROR_GENERIC;
  }

  return 0;
}



int test4(GWEN_UNUSED GWEN_TEST_MODULE *mod)
{
  static char path[]="test1:test2[3]:test3[2]";
  static PATH_TEST_ENTRY expected[]={
    {"test1", 0, AQH_PATH_FLAGS_PARSEIDX},
    {"test2", 3, AQH_PATH_FLAGS_PARSEIDX},
    {"test3", 2, AQH_PATH_FLAGS_PARSEIDX | AQH_PATH_FLAGS_LAST},
    {NULL,    0, 0}
  };

  if (AQH_Path_Handle(path, expected, AQH_PATH_FLAGS_PARSEIDX, ":", _cbTestElement)==NULL) {
    DBG_ERROR(NULL, "Error handling patch \"%s\"", path);
    return GWEN_ERROR_GENERIC;
  }

  return 0;
}






void *_cbTestElement(const char *element, void *data, int idx, uint32_t flags)
{
  PATH_TEST_ENTRY *currentEntry;

  DBG_INFO(NULL, "Testing element \"%s\":%d (%08x)", element, idx, flags);
  currentEntry=(PATH_TEST_ENTRY*) data;
  if (currentEntry->element==NULL) {
    DBG_ERROR(NULL, "current element is NULL when handling path element \"%s\"", element);
    return NULL;
  }

  if (idx!=currentEntry->index) {
    DBG_ERROR(NULL, "Current index \"%d\" doesn't match expected index \"%d\"", idx, currentEntry->index);
    return NULL;
  }

  if (flags!=currentEntry->flags) {
    DBG_ERROR(NULL, "Current flags \"%08x\" don't match expected flags \"%08x\"", flags, currentEntry->flags);
    return NULL;
  }

  if (strcmp(currentEntry->element, element)!=0) {
    DBG_ERROR(NULL, "Current element \"%s\" doesn't match expected element \"%s\"", element, currentEntry->element);
    return NULL;
  }

  currentEntry++;
  return currentEntry;
}





#else

int AQH_Path_AddTests(GWEN_TEST_MODULE *mod)
{
  DBG_ERROR(GWEN_LOGDOMAIN, "AqHome was compiled without test code enabled.");
  return GWEN_ERROR_GENERIC;
}


#endif
