#include "thumb.h"

static Ecore_Con_Url *fetch = NULL;
static Ecore_Event_Handler *handle_data = NULL;
static Ecore_Event_Handler *handle_complete = NULL;

static Eina_Strbuf *buf_str = NULL;
static size_t buf_str_max = 0;
static void *cb_str_data = NULL;
static void (*cb_str) (void *data, const char *result) = NULL;

static Eina_Strbuf *buf_bin = NULL;
static size_t buf_bin_max = 0;
static void *cb_bin_data = NULL;
static void (*cb_bin) (void *data, const void *result, size_t size) = NULL;

static Eina_Bool
_cb_http_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
   Ecore_Con_Event_Url_Data *ev = event;

   if (ev->url_con != fetch) return EINA_TRUE;
   if (buf_str)
     {
        eina_strbuf_append_length(buf_str, (char *)ev->data, (size_t)ev->size);
        if (eina_strbuf_length_get(buf_str) > buf_str_max)
          { // too big - abort whole fetch entirely
             ecore_con_url_free(fetch);
             fetch = NULL;
             cb_str(cb_str_data, NULL);
             cb_str = NULL;
             cb_str_data = NULL;
             eina_strbuf_free(buf_str);
             buf_str = NULL;
          }
     }
   else if (buf_bin)
     {
        eina_binbuf_append_length(buf_bin, (unsigned char *)ev->data, (size_t)ev->size);
        if (eina_binbuf_length_get(buf_bin) > buf_bin_max)
          { // too big - abort whole fetch entirely
             ecore_con_url_free(fetch);
             fetch = NULL;
             cb_bin(cb_bin_data, NULL, 0);
             cb_bin = NULL;
             cb_bin_data = NULL;
             eina_strbuf_free(buf_bin);
             buf_bin = NULL;
          }
     }
   return EINA_FALSE;
}

static Eina_Bool
_cb_http_complete(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
   Ecore_Con_Event_Url_Complete *ev = event;
   Eina_Strbuf *buf;

   if (ev->url_con != fetch) return EINA_TRUE;
   if (buf_str)
     {
        buf = buf_str;
        buf_str = NULL;
        ecore_con_url_free(fetch);
        fetch = NULL;
        cb_str(cb_str_data,
               eina_strbuf_string_get(buf));
        cb_str = NULL;
        cb_str_data = NULL;
        eina_strbuf_free(buf);
     }
   else if (buf_bin)
     {
        buf = buf_bin;
        buf_bin = NULL;
        ecore_con_url_free(fetch);
        fetch = NULL;
        cb_bin(cb_bin_data,
               eina_binbuf_string_get(buf),
               eina_binbuf_length_get(buf));
        cb_bin = NULL;
        cb_bin_data = NULL;
        eina_binbuf_free(buf);
     }
   return EINA_FALSE;
}

static Ecore_Con_Url *
_url_init(const char *url)
{
   Ecore_Con_Url *f;

   if (!handle_data)
     handle_data = ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA,
                                           _cb_http_data, NULL);
   if (!handle_complete)
     handle_complete = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE,
                                               _cb_http_complete, NULL);
   f = ecore_con_url_new(url);
   ecore_con_url_additional_header_add
     (f, "user-agent",
      "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19");
   ecore_con_url_get(f);
   return f;
}

void
thumb_url_str_get(const char *url, size_t max, void (*cb) (void *data, const char *result), const void *data)
{
   cb_str_data = (void *)data;
   cb_str = cb;
   buf_str = eina_strbuf_new();
   buf_str_max = max;
   fetch = _url_init(url);
}

void
thumb_url_bin_get(const char *url, size_t max, void (*cb) (void *data, const void *result, size_t size), const void *data)
{
   cb_bin_data = (void *)data;
   cb_bin = cb;
   buf_bin = eina_binbuf_new();
   buf_bin_max = max;
   fetch = _url_init(url);
}
