
#include <stdlib.h>
#include <pthread.h>

#include "responseholder.h"
#include "responseholderlist.h"

struct s_ResponseHolderList
{
    hshTvoid_list   *list;

    pthread_rwlock_t list_lock;

};

ResponseHolderList *
responseholderlist_new()
{
    ResponseHolderList *response_list = malloc (sizeof (ResponseHolderList));

    response_list->list = hshFvoid_int_init (responseholder_destroy);

    pthread_rwlock_init (&response_list->list_lock, NULL);

    return (response_list);
}

void
responseholderlist_destroy (void *ptr)
{
    ResponseHolderList *response_list = (ResponseHolderList *) ptr;

    pthread_rwlock_destroy (&response_list->list_lock);

    hshFvoid_destroy (response_list->list);

    free (response_list);
}


void
responseholderlist_addResponseHolder (ResponseHolderList *response_list, int sequence)
{
    ResponseHolder *resp = responseholder_new (sequence);

    pthread_rwlock_wrlock (&response_list->list_lock);

    hshFvoid_int_add (response_list->list, sequence, resp);

    pthread_rwlock_unlock (&response_list->list_lock);
}


static ResponseHolder *
responseholderlist_getResponseHolder (ResponseHolderList *response_list, int sequence)
{
    ResponseHolder *resp;

    pthread_rwlock_rdlock (&response_list->list_lock);

    resp = (ResponseHolder *) hshFvoid_int_find (response_list->list, sequence);

    pthread_rwlock_unlock (&response_list->list_lock);

    return (resp);
}

static void
responseholderlist_removeResponseHolder (ResponseHolderList *response_list, int sequence)
{
    pthread_rwlock_wrlock (&response_list->list_lock);

    hshFvoid_int_del (response_list->list, sequence);

    pthread_rwlock_unlock (&response_list->list_lock);
}

Message *
responseholderlist_getResponse (ResponseHolderList *response_list, int seq)
{
    Message *responseMessage;
    ResponseHolder *resp = responseholderlist_getResponseHolder (response_list, seq);
    
    responseMessage = responseholder_getResponse (resp);

    responseholderlist_removeResponseHolder (response_list, seq);

    return (responseMessage);
}

void
responseholderlist_setResponse (ResponseHolderList *response_list, Message *response)
{
    ResponseHolder *resp = responseholderlist_getResponseHolder (response_list,
            message_getSequence (response));

    if (resp != NULL)
    {
        responseholder_setResponse (resp, response);
    }
    else
    {
        /* we don't know what this is responding to */
    }
}

