#include "SynchronousLoader.h"
#include "NRCore/KWIQResponse.h"

#include "GLibHelpers.h"

SynchronousLoader::SynchronousLoader(const gchar* URL, GByteArray* outData, GHashTable* outHeaders)
    :responseHeaders(outHeaders)
    ,responseData(outData)
    ,response(0)
    ,loadFinished(false)
    
{
    assert(URL);
    currentURI = gnet_uri_new(URL);
    assert(currentURI); // DBC
}

SynchronousLoader::~SynchronousLoader()
{
    gnet_uri_delete(currentURI);
}

extern "C" {
static void _copy_hash_table_str_str(gpointer key, gpointer value, gpointer user_data)
{
    gchar* k = (gchar*) key;
    gchar* v = (gchar*) value;
    GHashTable* dest = (GHashTable*) user_data;

    g_hash_table_insert(dest, g_strdup(k), g_strdup(v));
}
}

void SynchronousLoader::receivedResponse(KWIQResponse* r)
{
    assert(r);
    response = r;
    GHashTable* headers = response->allHeaderFields();
    g_hash_table_foreach(headers, _copy_hash_table_str_str, responseHeaders);
}

void SynchronousLoader::redirectedToURL(const gchar* URL)
{
    assert(URL);

    GURI *newURI = 0;

    if (!isEmptyString(URL)) {
	GURI *newURI =  gnet_uri_new(URL);
	if (!newURI)
	    newURI = gnet_uri_new_relative(currentURI, URL);
    }
    if (!newURI){
	// redirection failed
	//XXX: Do something?
    } else {
	gnet_uri_delete(currentURI);
	currentURI = newURI;	    
    }
}

void SynchronousLoader::addData(const void *data,unsigned int length)
{
    assert(data || length == 0);

    if (length)
	g_byte_array_append (responseData, (const guint8*)data, length);
}

// Either finish, reportError, or cancel must be called before the
// loader is released, but never more than one.    
void SynchronousLoader::finish(void)
{
    loadFinished = true;    
}

void SynchronousLoader::reportError(void)
{
    loadFinished = true;
}

void SynchronousLoader::cancel(void)
{
    loadFinished = true;
}

int SynchronousLoader::statusCode() 
{ 
    if (response) return response->statusCode();
    return -1;
}
