/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "Config.h"

#include <stdio.h>
#include <strings.h>
#include <stdarg.h>

#include "Str.h"
#include "List.h"


/**
 * Implementation of the List interface. A freelist is used to retain
 * deleted nodes for reuse.
 *
 * @see http://www.mmonit.com/
 * @file
 */


/* ----------------------------------------------------------- Definitions */


#define T List_T


/* --------------------------------------------------------------- Private */


static inline list_t new_node(T L, void *e, list_t next) {
        list_t p;
        if (L->freelist) {
                p = L->freelist;
                L->freelist = p->next;
        } else
                p = ALLOC(sizeof *(p));
        p->e = e;
        p->next = next;
        return p;
}


/* ---------------------------------------------------------------- Public */


T List_new(void) {
 	T L;
        NEW(L);
	return L;
}


void List_free(T *L) {
        list_t p, q;
        assert(L && *L);
        for (p = (*L)->head; p; p = q) {
                q = p->next;
                FREE(p);
        }
        for (p = (*L)->freelist; p; p = q) {
                q = p->next;
                FREE(p);
        }
        FREE(*L);
}


void List_push(T L, void *e) {
        assert(L);
        list_t p = new_node(L, e, L->head);
        if (L->head == NULL)
                L->tail = p;
        L->head = p;
        L->length++;
        L->timestamp++;
}


void *List_pop(T L) {
        assert(L);
        if (L->head) {
                list_t p = L->head;
                L->head = L->head->next;
                L->length--;
                L->timestamp++;
                p->next = L->freelist;
                L->freelist = p;
                return p->e;
        } 
        return NULL;
}


void List_append(T L, void *e) {
        list_t p;
        assert(L);
        p = new_node(L, e, NULL);
        if (L->head == NULL)
                L->head = p;
        else
                L->tail->next = p;
        L->tail = p;
        L->length++;
        L->timestamp++;
}


void *List_remove(T L, void *e) {
        assert(L);
        if (e && L->head) {
                list_t p, q;
                if (L->head->e == e)
                        return List_pop(L);
                for (p = L->head; p; p = q) {
                        q = p->next;
                        if (q && (q->e == e)) {
                                p->next = q->next;
                                if (q == L->tail)
                                        L->tail = p;
                                p = q;
                                L->length--;
                                L->timestamp++;
                                p->next = L->freelist;
                                L->freelist = p;
                                return p->e;
                        }
                }
        }
        return NULL;
}


void List_cat(T L, T list) {
        assert(L);
        assert(list);
        if (L != list)
                for (list_t p = list->head; p; p = p->next)
                        List_append(L, p->e);
}


void List_reverse(T L) {
        list_t head, next, list;
        assert(L);
        head = NULL;
        list = L->head;
        L->tail = L->head;
	for (; list; list = next) {
                next = list->next;
                list->next = head;
                head = list;
	}
        L->head = head;
}


int List_length(T L) {
        assert(L);
        return L->length;
}


void List_clear(T L) {
        assert(L);
        if (L->tail) {
                L->tail->next = L->freelist;
                L->freelist = L->head;
        }
        L->tail = L->head = NULL;
        L->length = 0;
}


void List_map(T L, void (*apply)(void *e, void *ap), void *ap) {
        int stamp;
        list_t p;
        assert(L);
        stamp = L->timestamp;
        assert(apply);
        for (p = L->head; p; p = p->next) {
                apply(p->e, ap);
                assert(L->timestamp == stamp);
        }
}


void **List_toArray(T L) {
        assert(L);
        int i = 0;
        void **array = ALLOC((L->length + 1) * sizeof *(array)); 
        for (list_t p = L->head; p; p = p->next, i++)
                array[i] = p->e;
        array[i] = NULL;
        return array;
}


