/**
 * @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 *rec2;

    assert(rec);

    /* remove links of leafref nodes */
    LY_ARRAY_FOR(rec->leafref_nodes, u) {
        if (lyd_get_or_create_leafref_links_record(rec->leafref_nodes[u], &rec2, 0) == LY_SUCCESS) {
            LY_ARRAY_REMOVE_VALUE(rec2->target_nodes, rec->node);
            if ((LY_ARRAY_COUNT(rec2->leafref_nodes) == 0) && (LY_ARRAY_COUNT(rec2->target_nodes) == 0)) {
                lyd_free_leafref_nodes(rec->leafref_nodes[u]);
            }
        }
    }
    LY_ARRAY_FREE(rec->leafref_nodes);
    rec->leafref_nodes = NULL;

    /* remove links of target nodes */
    LY_ARRAY_FOR(rec->target_nodes, u) {
        if (lyd_get_or_create_leafref_links_record(rec->target_nodes[u], &rec2, 0) == LY_SUCCESS) {
            LY_ARRAY_REMOVE_VALUE(rec2->leafref_nodes, rec->node);
            if ((LY_ARRAY_COUNT(rec2->leafref_nodes) == 0) && (LY_ARRAY_COUNT(rec2->target_nodes) == 0)) {
                lyd_free_leafref_nodes(rec->target_nodes[u]);
            }
        }
    }
    LY_ARRAY_FREE(rec->target_nodes);
    rec->target_nodes = NULL;
}

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);
}
