/**
 * @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 <stdlib.h>
#include <string.h>
#include <stdint.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, 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, uint32_t options, uint32_t *index_p)
{
    void **new;

    LY_CHECK_ARG_RET(NULL, set, LY_EINVAL);

    if (!(options & LY_SET_OPT_USEASLIST)) {
        /* 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) {
        new = realloc(set->objs, (set->size + 8) * sizeof *(set->objs));
        LY_CHECK_ERR_RET(!new, LOGMEM(NULL), LY_EMEM);
        set->size += 8;
        set->objs = new;
    }

    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, struct ly_set *src, uint32_t options, 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, options, 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);
}
