/**
 * @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 = malloc(sizeof *newset);
    LY_CHECK_ERR_RET(!newset, LOGMEM(NULL), LY_EMEM);
    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);
}
