#include <Eina.h>
#include "eina_blist.h"

unsigned int N = 0;
unsigned int L = 0;

static unsigned int dump2(Eina_List *l)
{
   Eina_List *it;
   void *d;
   unsigned int i = 0;

   EINA_LIST_FOREACH(l, it, d)
     {
//        printf("IT: [%u] %i\n", i, (int)(uintptr_t)d);
        i++;
     }
   return i;
}

static unsigned int dumprev2(Eina_List *l)
{
   Eina_List *it;
   void *d;
   unsigned int i = 0;

   EINA_LIST_REVERSE_FOREACH(l, it, d)
     {
//        printf("IT: [%u] %i\n", i, (int)(uintptr_t)d);
        i++;
     }
   return i;
}

static void list_test(void)
{
   Eina_List *l = NULL;
   int i;

   for (i = 1; i < N; i++)
     {
        l = eina_list_append(l, (void *)(uintptr_t)i);
     }
   if (dump2(l) > 12345) printf("");
   if (dumprev2(l) > 12345) printf("");
   for (i = 0; i < N; i++)
     {
        l = eina_list_prepend(l, (void *)(uintptr_t)i);
     }
   if (dump2(l) > 12345) printf("");
   if (dumprev2(l) > 12345) printf("");

   for (i = 0; i < N; i += 123)
     {
        l = eina_list_remove(l, (void *)(uintptr_t)i);
     }
   if (dump2(l) > 12345) printf("");
   if (dumprev2(l) > 12345) printf("");

   for (i = 0; i < N; i += 123)
     {
        l = eina_list_append_relative(l, (void *)(uintptr_t)i, (void *)(uintptr_t)450);
     }
   for (i = 0; i < N; i += 123)
     {
        l = eina_list_prepend_relative(l, (void *)(uintptr_t)i, (void *)(uintptr_t)450);
     }
   if (dump2(l) > 12345) printf("");
   if (dumprev2(l) > 12345) printf("");
   if (dump2(l) > 12345) printf("");
   if (dumprev2(l) > 12345) printf("");
   if (dump2(l) > 12345) printf("");
   if (dumprev2(l) > 12345) printf("");
   if (dump2(l) > 12345) printf("");
   if (dumprev2(l) > 12345) printf("");
   l = eina_list_free(l);
}

static unsigned int dump(Eina_Blist *l)
{
   Eina_Blist_Item *it;
   void *d;
   unsigned int i = 0;

   EINA_BLIST_FOREACH(&l, it, d)
     {
//        printf("IT: [%u] %i\n", i, (int)(uintptr_t)d);
        i++;
     }
   return i;
}

static unsigned int dumprev(Eina_Blist *l)
{
   Eina_Blist_Item *it;
   void *d;
   unsigned int i = 0;

   EINA_BLIST_REVERSE_FOREACH(&l, it, d)
     {
//        printf("IT: [%u] %i\n", i, (int)(uintptr_t)d);
        i++;
     }
   return i;
}

static void blist_test(void)
{
   Eina_Blist *l = NULL;
   int i;

   for (i = 1; i < N; i++)
     {
        eina_blist_append(&l, (void *)(uintptr_t)i);
     }
   if (dump(l) > 12345) printf("");
   if (dumprev(l) > 12345) printf("");
   for (i = 0; i < N; i++)
     {
        eina_blist_prepend(&l, (void *)(uintptr_t)i);
     }
   if (dump(l) > 12345) printf("");
   if (dumprev(l) > 12345) printf("");

   for (i = 0; i < N; i += 123)
     {
        eina_blist_remove(&l, (void *)(uintptr_t)i);
     }
   if (dump(l) > 12345) printf("");
   if (dumprev(l) > 12345) printf("");

   for (i = 0; i < N; i += 123)
     {
        eina_blist_relative_append(&l, (void *)(uintptr_t)i, (void *)(uintptr_t)450);
     }
   for (i = 0; i < N; i += 123)
     {
        eina_blist_relative_prepend(&l, (void *)(uintptr_t)i, (void *)(uintptr_t)450);
     }
   if (dump(l) > 12345) printf("");
   if (dumprev(l) > 12345) printf("");
   if (dump(l) > 12345) printf("");
   if (dumprev(l) > 12345) printf("");
   if (dump(l) > 12345) printf("");
   if (dumprev(l) > 12345) printf("");
   if (dump(l) > 12345) printf("");
   if (dumprev(l) > 12345) printf("");
   eina_blist_free(&l);
}

int main(int argc, char **argv)
{
   unsigned int l;

   if (argc < 4)
     {
        printf("Need arg: [blist | list] ITEMS LOOPS\n");
        return 0;
     }
   N = atoi(argv[2]);
   L = atoi(argv[3]);
   eina_init();
   if      (!strcmp(argv[1], "blist")) for (l = 0; l < L; l++) blist_test();
   else if (!strcmp(argv[1], "list"))  for (l = 0; l < L; l++) list_test();
   eina_shutdown();
}
