/**
 * @file tree_data_free.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief Freeing functions for data tree structures
 *
 * Copyright (c) 2019 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 <assert.h>
#include <stdlib.h>

#include "common.h"
#include "dict.h"
#include "hash_table.h"
#include "log.h"
#include "plugins_exts/metadata.h"
#include "plugins_types.h"
#include "tree.h"
#include "tree_data.h"
#include "tree_data_internal.h"
#include "tree_schema.h"

static void
lyd_free_meta(struct lyd_meta *meta, ly_bool siblings)
{
    struct lyd_meta *iter;

    if (!meta) {
        return;
    }

    if (meta->parent) {
        if (meta->parent->meta == meta) {
            if (siblings) {
                meta->parent->meta = NULL;
            } else {
                meta->parent->meta = meta->next;
            }
        } else {
            for (iter = meta->parent->meta; iter->next != meta; iter = iter->next) {}
            if (iter->next) {
                if (siblings) {
                    iter->next = NULL;
                } else {
                    iter->next = meta->next;
                }
            }
        }
    }

    if (!siblings) {
        meta->next = NULL;
    }

    for (iter = meta; iter; ) {
        meta = iter;
        iter = iter->next;

        lydict_remove(meta->annotation->module->ctx, meta->name);
        meta->value.realtype->plugin->free(meta->annotation->module->ctx, &meta->value);
        free(meta);
    }
}

LIBYANG_API_DEF void
lyd_free_meta_single(struct lyd_meta *meta)
{
    lyd_free_meta(meta, 0);
}

LIBYANG_API_DEF void
lyd_free_meta_siblings(struct lyd_meta *meta)
{
    lyd_free_meta(meta, 1);
}

static void
lyd_free_attr(const struct ly_ctx *ctx, struct lyd_attr *attr, ly_bool siblings)
{
    struct lyd_attr *iter;

    LY_CHECK_ARG_RET(NULL, ctx, );
    if (!attr) {
        return;
    }

    if (attr->parent) {
        if (attr->parent->attr == attr) {
            if (siblings) {
                attr->parent->attr = NULL;
            } else {
                attr->parent->attr = attr->next;
            }
        } else {
            for (iter = attr->parent->attr; iter->next != attr; iter = iter->next) {}
            if (iter->next) {
                if (siblings) {
                    iter->next = NULL;
                } else {
                    iter->next = attr->next;
                }
            }
        }
    }

    if (!siblings) {
        attr->next = NULL;
    }

    for (iter = attr; iter; ) {
        attr = iter;
        iter = iter->next;

        ly_free_prefix_data(attr->format, attr->val_prefix_data);
        lydict_remove(ctx, attr->name.name);
        lydict_remove(ctx, attr->name.prefix);
        lydict_remove(ctx, attr->name.module_ns);
        lydict_remove(ctx, attr->value);
        free(attr);
    }
}

LIBYANG_API_DEF void
lyd_free_attr_single(const struct ly_ctx *ctx, struct lyd_attr *attr)
{
    lyd_free_attr(ctx, attr, 0);
}

LIBYANG_API_DEF void
lyd_free_attr_siblings(const struct ly_ctx *ctx, struct lyd_attr *attr)
{
    lyd_free_attr(ctx, attr, 1);
}

void
lyd_free_leafref_links_rec(struct lyd_leafref_links_rec *rec)
{
    LY_ARRAY_COUNT_TYPE u;
    struct lyd_leafref_links_rec *leafref_rec;

    assert(rec);

    /* remove stored leafref nodes */
    LY_ARRAY_FOR(rec->leafref_nodes, u) {
        if (lyd_get_or_create_leafref_links_record(rec->leafref_nodes[u], &leafref_rec, 0) == LY_SUCCESS) {
            leafref_rec->target_node = NULL;
            if (!LY_ARRAY_COUNT(leafref_rec->leafref_nodes) && !leafref_rec->target_node) {
                lyd_free_leafref_nodes(rec->leafref_nodes[u]);
            }
        }
    }
    LY_ARRAY_FREE(rec->leafref_nodes);
    rec->leafref_nodes = NULL;

    /* remove stored target node */
    if (rec->target_node) {
        lyd_unlink_leafref_node(rec->target_node, rec->node);
    }
}

void
lyd_free_leafref_nodes(const struct lyd_node_term *node)
{
    struct ly_ht *ht;
    uint32_t hash;
    struct lyd_leafref_links_rec *rec;

    assert(node);

    if (lyd_get_or_create_leafref_links_record(node, &rec, 0)) {
        return;
    }

    /* free entry content */
    lyd_free_leafref_links_rec(rec);

    /* free entry itself from hash table */
    ht = LYD_CTX(node)->leafref_links_ht;
    hash = lyht_hash((const char *)&node, sizeof node);
    lyht_remove(ht, rec, hash);
}

/**
 * @brief Free Data (sub)tree.
 *
 * @param[in] node Data node to be freed.
 * @param[in] top Recursion flag to unlink the root of the subtree being freed.
 */
static void
lyd_free_subtree(struct lyd_node *node, ly_bool top)
{
    struct lyd_node *iter, *next;
    struct lyd_node_opaq *opaq = NULL;

    assert(node);

    if (!node->schema) {
        opaq = (struct lyd_node_opaq *)node;

        /* free the children */
        LY_LIST_FOR_SAFE(lyd_child(node), next, iter) {
            lyd_free_subtree(iter, 0);
        }

        lydict_remove(LYD_CTX(opaq), opaq->name.name);
        lydict_remove(LYD_CTX(opaq), opaq->name.prefix);
        lydict_remove(LYD_CTX(opaq), opaq->name.module_ns);
        lydict_remove(LYD_CTX(opaq), opaq->value);
        ly_free_prefix_data(opaq->format, opaq->val_prefix_data);
    } else if (node->schema->nodetype & LYD_NODE_INNER) {
        /* remove children hash table in case of inner data node */
        lyht_free(((struct lyd_node_inner *)node)->children_ht, NULL);
        ((struct lyd_node_inner *)node)->children_ht = NULL;

        /* free the children */
        LY_LIST_FOR_SAFE(lyd_child(node), next, iter) {
            lyd_free_subtree(iter, 0);
        }
    } else if (node->schema->nodetype & LYD_NODE_ANY) {
        /* only frees the value this way */
        lyd_any_copy_value(node, NULL, 0);
    } else if (node->schema->nodetype & LYD_NODE_TERM) {
        struct lyd_node_term *node_term = (struct lyd_node_term *)node;

        ((struct lysc_node_leaf *)node->schema)->type->plugin->free(LYD_CTX(node), &node_term->value);
        lyd_free_leafref_nodes(node_term);
    }

    if (!node->schema) {
        lyd_free_attr_siblings(LYD_CTX(node), opaq->attr);
    } else {
        /* free the node's metadata */
        lyd_free_meta_siblings(node->meta);
    }

    /* unlink only the nodes from the first level, nodes in subtree are freed all, so no unlink is needed */
    if (top) {
        lyd_unlink(node);
    }

    free(node);
}

LIBYANG_API_DEF void
lyd_free_tree(struct lyd_node *node)
{
    if (!node) {
        return;
    }

    if (lysc_is_key(node->schema) && node->parent) {
        LOGERR(LYD_CTX(node), LY_EINVAL, "Cannot free a list key \"%s\", free the list instance instead.", LYD_NAME(node));
        return;
    }

    lyd_free_subtree(node, 1);
}

static void
lyd_free_(struct lyd_node *node, ly_bool top)
{
    struct lyd_node *iter, *next;

    if (!node) {
        return;
    }

    /* get the first (top-level) sibling */
    if (top) {
        for ( ; node->parent; node = lyd_parent(node)) {}
    }
    while (node->prev->next) {
        node = node->prev;
    }

    LY_LIST_FOR_SAFE(node, next, iter) {
        if (lysc_is_key(iter->schema) && iter->parent) {
            LOGERR(LYD_CTX(iter), LY_EINVAL, "Cannot free a list key \"%s\", free the list instance instead.", LYD_NAME(iter));
            return;
        }

        /* in case of the top-level nodes (node->parent is NULL), no unlinking needed */
        lyd_free_subtree(iter, iter->parent ? 1 : 0);
    }
}

LIBYANG_API_DEF void
lyd_free_siblings(struct lyd_node *node)
{
    lyd_free_(node, 0);
}

LIBYANG_API_DEF void
lyd_free_all(struct lyd_node *node)
{
    lyd_free_(node, 1);
}
