/**
 * @file set.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief Generic set routines implementations
 *
 * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#include "common.h"

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "log.h"
#include "set.h"

API LY_ERR
ly_set_new(struct ly_set **set_p)
{
    LY_CHECK_ARG_RET(NULL, set_p, LY_EINVAL);

    *set_p = calloc(1, sizeof **set_p);
    LY_CHECK_ERR_RET(!(*set_p), LOGMEM(NULL), LY_EMEM);

    return LY_SUCCESS;
}

API void
ly_set_clean(struct ly_set *set, void (*destructor)(void *obj))
{
    uint32_t u;

    if (!set) {
        return;
    }

    if (destructor) {
        for (u = 0; u < set->count; ++u) {
            destructor(set->objs[u]);
        }
    }
    set->count = 0;
}

API void
ly_set_erase(struct ly_set *set, void (*destructor)(void *obj))
{
    if (!set) {
        return;
    }

    ly_set_clean(set, destructor);

    free(set->objs);
    set->size = 0;
    set->objs = NULL;
}

API void
ly_set_free(struct ly_set *set, void (*destructor)(void *obj))
{
    if (!set) {
        return;
    }

    ly_set_erase(set, destructor);

    free(set);
}

API ly_bool
ly_set_contains(const struct ly_set *set, void *object, uint32_t *index_p)
{
    LY_CHECK_ARG_RET(NULL, set, 0);

    for (uint32_t i = 0; i < set->count; i++) {
        if (set->objs[i] == object) {
            /* object found */
            if (index_p) {
                *index_p = i;
            }
            return 1;
        }
    }

    /* object not found */
    return 0;
}

API LY_ERR
ly_set_dup(const struct ly_set *set, void *(*duplicator)(void *obj), struct ly_set **newset_p)
{
    struct ly_set *newset;
    uint32_t u;

    LY_CHECK_ARG_RET(NULL, set, newset_p, LY_EINVAL);

    newset = calloc(1, sizeof *newset);
    LY_CHECK_ERR_RET(!newset, LOGMEM(NULL), LY_EMEM);
    if (!set->count) {
        *newset_p = newset;
        return LY_SUCCESS;
    }

    newset->count = set->count;
    newset->size = set->count; /* optimize the size */
    newset->objs = malloc(newset->size * sizeof *(newset->objs));
    LY_CHECK_ERR_RET(!newset->objs, LOGMEM(NULL); free(newset), LY_EMEM);
    if (duplicator) {
        for (u = 0; u < set->count; ++u) {
            newset->objs[u] = duplicator(set->objs[u]);
        }
    } else {
        memcpy(newset->objs, set->objs, newset->size * sizeof *(newset->objs));
    }

    *newset_p = newset;
    return LY_SUCCESS;
}

API LY_ERR
ly_set_add(struct ly_set *set, void *object, ly_bool list, uint32_t *index_p)
{
    void **new;

    LY_CHECK_ARG_RET(NULL, set, LY_EINVAL);

    if (!list) {
        /* search for duplication */
        for (uint32_t i = 0; i < set->count; i++) {
            if (set->objs[i] == object) {
                /* already in set */
                if (index_p) {
                    *index_p = i;
                }
                return LY_SUCCESS;
            }
        }
    }

    if (set->size == set->count) {
#define SET_SIZE_STEP 8
        new = realloc(set->objs, (set->size + SET_SIZE_STEP) * sizeof *(set->objs));
        LY_CHECK_ERR_RET(!new, LOGMEM(NULL), LY_EMEM);
        set->size += SET_SIZE_STEP;
        set->objs = new;
#undef SET_SIZE_STEP
    }

    if (index_p) {
        *index_p = set->count;
    }
    set->objs[set->count++] = object;

    return LY_SUCCESS;
}

API LY_ERR
ly_set_merge(struct ly_set *trg, const struct ly_set *src, ly_bool list, void *(*duplicator)(void *obj))
{
    uint32_t u;
    void *obj;

    LY_CHECK_ARG_RET(NULL, trg, LY_EINVAL);

    if (!src) {
        /* nothing to do */
        return LY_SUCCESS;
    }

    for (u = 0; u < src->count; ++u) {
        if (duplicator) {
            obj = duplicator(src->objs[u]);
        } else {
            obj = src->objs[u];
        }
        LY_CHECK_RET(ly_set_add(trg, obj, list, NULL));
    }

    return LY_SUCCESS;
}

API LY_ERR
ly_set_rm_index(struct ly_set *set, uint32_t index, void (*destructor)(void *obj))
{
    LY_CHECK_ARG_RET(NULL, set, LY_EINVAL);
    LY_CHECK_ERR_RET(index >= set->count, LOGARG(NULL, index), LY_EINVAL);

    if (destructor) {
        destructor(set->objs[index]);
    }
    if (index == set->count - 1) {
        /* removing last item in set */
        set->objs[index] = NULL;
    } else {
        /* removing item somewhere in a middle, so put there the last item */
        set->objs[index] = set->objs[set->count - 1];
        set->objs[set->count - 1] = NULL;
    }
    set->count--;

    return LY_SUCCESS;
}

API LY_ERR
ly_set_rm(struct ly_set *set, void *object, void (*destructor)(void *obj))
{
    uint32_t i;

    LY_CHECK_ARG_RET(NULL, set, object, LY_EINVAL);

    /* get index */
    for (i = 0; i < set->count; i++) {
        if (set->objs[i] == object) {
            break;
        }
    }
    LY_CHECK_ERR_RET((i == set->count), LOGARG(NULL, object), LY_EINVAL); /* object is not in set */

    return ly_set_rm_index(set, i, destructor);
}

LY_ERR
ly_set_rm_index_ordered(struct ly_set *set, uint32_t index, void (*destructor)(void *obj))
{
    if (destructor) {
        destructor(set->objs[index]);
    }
    set->count--;
    if (index == set->count) {
        /* removing last item in set */
        set->objs[index] = NULL;
    } else {
        /* removing item somewhere in a middle, move following items */
        memmove(set->objs + index, set->objs + index + 1, (set->count - index) * sizeof *set->objs);
        set->objs[set->count] = NULL;
    }

    return LY_SUCCESS;
}
