/**
 * @file validation.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief Validation
 *
 * Copyright (c) 2019 - 2022 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
 */
#define _GNU_SOURCE /* asprintf, strdup */

#include "validation.h"

#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common.h"
#include "compat.h"
#include "diff.h"
#include "hash_table.h"
#include "log.h"
#include "parser_data.h"
#include "parser_internal.h"
#include "plugins_exts.h"
#include "plugins_exts/metadata.h"
#include "plugins_types.h"
#include "set.h"
#include "tree.h"
#include "tree_data.h"
#include "tree_data_internal.h"
#include "tree_schema.h"
#include "tree_schema_internal.h"
#include "xpath.h"

LY_ERR
lyd_val_diff_add(const struct lyd_node *node, enum lyd_diff_op op, struct lyd_node **diff)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyd_node *new_diff = NULL;
    const struct lyd_node *prev_inst;
    char *key = NULL, *value = NULL, *position = NULL;
    size_t buflen = 0, bufused = 0;
    uint32_t pos;

    assert((op == LYD_DIFF_OP_DELETE) || (op == LYD_DIFF_OP_CREATE));

    if ((op == LYD_DIFF_OP_CREATE) && lysc_is_userordered(node->schema)) {
        if (lysc_is_dup_inst_list(node->schema)) {
            pos = lyd_list_pos(node);

            /* generate position meta */
            if (pos > 1) {
                if (asprintf(&position, "%" PRIu32, pos - 1) == -1) {
                    LOGMEM(LYD_CTX(node));
                    ret = LY_EMEM;
                    goto cleanup;
                }
            } else {
                position = strdup("");
                LY_CHECK_ERR_GOTO(!position, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
            }
        } else {
            if (node->prev->next && (node->prev->schema == node->schema)) {
                prev_inst = node->prev;
            } else {
                /* first instance */
                prev_inst = NULL;
            }

            if (node->schema->nodetype == LYS_LIST) {
                /* generate key meta */
                if (prev_inst) {
                    LY_CHECK_GOTO(ret = lyd_path_list_predicate(prev_inst, &key, &buflen, &bufused, 0), cleanup);
                } else {
                    key = strdup("");
                    LY_CHECK_ERR_GOTO(!key, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
                }
            } else {
                /* generate value meta */
                if (prev_inst) {
                    value = strdup(lyd_get_value(prev_inst));
                    LY_CHECK_ERR_GOTO(!value, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
                } else {
                    value = strdup("");
                    LY_CHECK_ERR_GOTO(!value, LOGMEM(LYD_CTX(node)); ret = LY_EMEM, cleanup);
                }
            }
        }
    }

    /* create new diff tree */
    LY_CHECK_GOTO(ret = lyd_diff_add(node, op, NULL, NULL, key, value, position, NULL, NULL, &new_diff), cleanup);

    /* merge into existing diff */
    ret = lyd_diff_merge_all(diff, new_diff, 0);

cleanup:
    lyd_free_tree(new_diff);
    free(key);
    free(value);
    free(position);
    return ret;
}

/**
 * @brief Evaluate all relevant "when" conditions of a node.
 *
 * @param[in] tree Data tree.
 * @param[in] node Node whose relevant when conditions will be evaluated.
 * @param[in] schema Schema node of @p node. It may not be possible to use directly if @p node is opaque.
 * @param[in] xpath_options Additional XPath options to use.
 * @param[out] disabled First when that evaluated false, if any.
 * @return LY_SUCCESS on success.
 * @return LY_EINCOMPLETE if a referenced node does not have its when evaluated.
 * @return LY_ERR value on error.
 */
static LY_ERR
lyd_validate_node_when(const struct lyd_node *tree, const struct lyd_node *node, const struct lysc_node *schema,
        uint32_t xpath_options, const struct lysc_when **disabled)
{
    LY_ERR ret;
    const struct lyd_node *ctx_node;
    struct lyxp_set xp_set;
    LY_ARRAY_COUNT_TYPE u;

    assert(!node->schema || (node->schema == schema));

    *disabled = NULL;

    do {
        const struct lysc_when *when;
        struct lysc_when **when_list = lysc_node_when(schema);

        LY_ARRAY_FOR(when_list, u) {
            when = when_list[u];

            /* get context node */
            if (when->context == schema) {
                ctx_node = node;
            } else {
                assert((!when->context && !node->parent) || (when->context == node->parent->schema));
                ctx_node = lyd_parent(node);
            }

            /* evaluate when */
            memset(&xp_set, 0, sizeof xp_set);
            ret = lyxp_eval(LYD_CTX(node), when->cond, schema->module, LY_VALUE_SCHEMA_RESOLVED, when->prefixes,
                    ctx_node, ctx_node, tree, NULL, &xp_set, LYXP_SCHEMA | xpath_options);
            lyxp_set_cast(&xp_set, LYXP_SET_BOOLEAN);

            /* return error or LY_EINCOMPLETE for dependant unresolved when */
            LY_CHECK_RET(ret);

            if (!xp_set.val.bln) {
                /* false when */
                *disabled = when;
                return LY_SUCCESS;
            }
        }

        schema = schema->parent;
    } while (schema && (schema->nodetype & (LYS_CASE | LYS_CHOICE)));

    return LY_SUCCESS;
}

/**
 * @brief Evaluate when conditions of collected unres nodes.
 *
 * @param[in,out] tree Data tree, is updated if some nodes are autodeleted.
 * @param[in] mod Module of the @p tree to take into consideration when deleting @p tree and moving it.
 * If set, it is expected @p tree should point to the first node of @p mod. Otherwise it will simply be
 * the first top-level sibling.
 * @param[in] node_when Set with nodes with "when" conditions.
 * @param[in] xpath_options Additional XPath options to use.
 * @param[in,out] node_types Set with nodes with unresolved types, remove any with false "when" parents.
 * @param[in,out] diff Validation diff.
 * @return LY_SUCCESS on success.
 * @return LY_ERR value on error.
 */
static LY_ERR
lyd_validate_unres_when(struct lyd_node **tree, const struct lys_module *mod, struct ly_set *node_when,
        uint32_t xpath_options, struct ly_set *node_types, struct lyd_node **diff)
{
    LY_ERR rc, r;
    uint32_t i, idx;
    const struct lysc_when *disabled;
    struct lyd_node *node = NULL, *elem;

    if (!node_when->count) {
        return LY_SUCCESS;
    }

    i = node_when->count;
    do {
        --i;
        node = node_when->dnodes[i];
        LOG_LOCSET(node->schema, node, NULL, NULL);

        /* evaluate all when expressions that affect this node's existence */
        r = lyd_validate_node_when(*tree, node, node->schema, xpath_options, &disabled);
        if (!r) {
            if (disabled) {
                /* when false */
                if (node->flags & LYD_WHEN_TRUE) {
                    /* autodelete */
                    lyd_del_move_root(tree, node, mod);
                    if (diff) {
                        /* add into diff */
                        LY_CHECK_GOTO(rc = lyd_val_diff_add(node, LYD_DIFF_OP_DELETE, diff), error);
                    }

                    /* remove from node types set, if present */
                    if (node_types && node_types->count) {
                        LYD_TREE_DFS_BEGIN(node, elem) {
                            /* only term nodes with a validation callback can be in node_types */
                            if ((elem->schema->nodetype & LYD_NODE_TERM) &&
                                    ((struct lysc_node_leaf *)elem->schema)->type->plugin->validate &&
                                    ly_set_contains(node_types, elem, &idx)) {
                                LY_CHECK_GOTO(rc = ly_set_rm_index(node_types, idx, NULL), error);
                            }
                            LYD_TREE_DFS_END(node, elem);
                        }
                    }

                    /* free */
                    lyd_free_tree(node);
                } else {
                    /* invalid data */
                    LOGVAL(LYD_CTX(node), LY_VCODE_NOWHEN, disabled->cond->expr);
                    rc = LY_EVALID;
                    goto error;
                }
            } else {
                /* when true */
                node->flags |= LYD_WHEN_TRUE;
            }

            /* remove this node from the set keeping the order, its when was resolved */
            ly_set_rm_index_ordered(node_when, i, NULL);
        } else if (r != LY_EINCOMPLETE) {
            /* error */
            rc = r;
            goto error;
        }

        LOG_LOCBACK(1, 1, 0, 0);
    } while (i);

    return LY_SUCCESS;

error:
    LOG_LOCBACK(1, 1, 0, 0);
    return rc;
}

LY_ERR
lyd_validate_unres(struct lyd_node **tree, const struct lys_module *mod, enum lyd_type data_type, struct ly_set *node_when,
        uint32_t when_xp_opts, struct ly_set *node_types, struct ly_set *meta_types, struct ly_set *ext_node,
        struct ly_set *ext_val, uint32_t val_opts, struct lyd_node **diff)
{
    LY_ERR ret = LY_SUCCESS;
    uint32_t i;

    if (ext_val && ext_val->count) {
        /* first validate parsed extension data */
        i = ext_val->count;
        do {
            --i;

            struct lyd_ctx_ext_val *ext_v = ext_val->objs[i];

            /* validate extension data */
            ret = ext_v->ext->def->plugin->validate(ext_v->ext, ext_v->sibling, *tree, data_type, val_opts, diff);
            LY_CHECK_RET(ret);

            /* remove this item from the set */
            ly_set_rm_index(ext_val, i, free);
        } while (i);
    }

    if (ext_node && ext_node->count) {
        /* validate data nodes with extension instances */
        i = ext_node->count;
        do {
            --i;

            struct lyd_ctx_ext_node *ext_n = ext_node->objs[i];

            /* validate the node */
            ret = ext_n->ext->def->plugin->node(ext_n->ext, ext_n->node, val_opts);
            LY_CHECK_RET(ret);

            /* remove this item from the set */
            ly_set_rm_index(ext_node, i, free);
        } while (i);
    }

    if (node_when) {
        /* evaluate all when conditions */
        uint32_t prev_count;

        do {
            prev_count = node_when->count;
            LY_CHECK_RET(lyd_validate_unres_when(tree, mod, node_when, when_xp_opts, node_types, diff));
            /* there must have been some when conditions resolved */
        } while (prev_count > node_when->count);

        /* there could have been no cyclic when dependencies, checked during compilation */
        assert(!node_when->count);
    }

    if (node_types && node_types->count) {
        /* finish incompletely validated terminal values (traverse from the end for efficient set removal) */
        i = node_types->count;
        do {
            --i;

            struct lyd_node_term *node = node_types->objs[i];
            struct lysc_type *type = ((struct lysc_node_leaf *)node->schema)->type;

            /* resolve the value of the node */
            LOG_LOCSET(NULL, &node->node, NULL, NULL);
            ret = lyd_value_validate_incomplete(LYD_CTX(node), type, &node->value, &node->node, *tree);
            LOG_LOCBACK(0, 1, 0, 0);
            LY_CHECK_RET(ret);

            /* remove this node from the set */
            ly_set_rm_index(node_types, i, NULL);
        } while (i);
    }

    if (meta_types && meta_types->count) {
        /* ... and metadata values */
        i = meta_types->count;
        do {
            --i;

            struct lyd_meta *meta = meta_types->objs[i];
            struct lysc_type *type;

            /* validate and store the value of the metadata */
            lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, sizeof type, (const void **)&type);
            ret = lyd_value_validate_incomplete(LYD_CTX(meta->parent), type, &meta->value, meta->parent, *tree);
            LY_CHECK_RET(ret);

            /* remove this attr from the set */
            ly_set_rm_index(meta_types, i, NULL);
        } while (i);
    }

    return ret;
}

/**
 * @brief Validate instance duplication.
 *
 * @param[in] first First sibling to search in.
 * @param[in] node Data node instance to check.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_duplicates(const struct lyd_node *first, const struct lyd_node *node)
{
    struct lyd_node **match_p;
    ly_bool fail = 0;

    assert(node->flags & LYD_NEW);

    /* key-less list or non-configuration leaf-list */
    if (lysc_is_dup_inst_list(node->schema)) {
        /* duplicate instances allowed */
        return LY_SUCCESS;
    }

    /* find exactly the same next instance using hashes if possible */
    if (node->parent && node->parent->children_ht) {
        if (!lyht_find_next(node->parent->children_ht, &node, node->hash, (void **)&match_p)) {
            fail = 1;
        }
    } else {
        for ( ; first; first = first->next) {
            if (first == node) {
                continue;
            }

            if (node->schema->nodetype & (LYD_NODE_ANY | LYS_LEAF)) {
                if (first->schema == node->schema) {
                    fail = 1;
                    break;
                }
            } else if (!lyd_compare_single(first, node, 0)) {
                fail = 1;
                break;
            }
        }
    }

    if (fail) {
        LOGVAL(node->schema->module->ctx, LY_VCODE_DUP, node->schema->name);
        return LY_EVALID;
    }
    return LY_SUCCESS;
}

/**
 * @brief Validate multiple case data existence with possible autodelete.
 *
 * @param[in,out] first First sibling to search in, is updated if needed.
 * @param[in] mod Module of the siblings, NULL for nested siblings.
 * @param[in] choic Choice node whose cases to check.
 * @param[in,out] diff Validation diff.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_cases(struct lyd_node **first, const struct lys_module *mod, const struct lysc_node_choice *choic,
        struct lyd_node **diff)
{
    const struct lysc_node *scase, *iter, *old_case = NULL, *new_case = NULL;
    struct lyd_node *match, *to_del;
    ly_bool found;

    LOG_LOCSET(&choic->node, NULL, NULL, NULL);

    LY_LIST_FOR((struct lysc_node *)choic->cases, scase) {
        found = 0;
        iter = NULL;
        match = NULL;
        while ((match = lys_getnext_data(match, *first, &iter, scase, NULL))) {
            if (match->flags & LYD_NEW) {
                /* a new case data found, nothing more to look for */
                found = 2;
                break;
            } else {
                /* and old case data found */
                if (found == 0) {
                    found = 1;
                }
            }
        }

        if (found == 1) {
            /* there should not be 2 old cases */
            if (old_case) {
                /* old data from 2 cases */
                LOGVAL(choic->module->ctx, LY_VCODE_DUPCASE, old_case->name, scase->name);
                LOG_LOCBACK(1, 0, 0, 0);
                return LY_EVALID;
            }

            /* remember an old existing case */
            old_case = scase;
        } else if (found == 2) {
            if (new_case) {
                /* new data from 2 cases */
                LOGVAL(choic->module->ctx, LY_VCODE_DUPCASE, new_case->name, scase->name);
                LOG_LOCBACK(1, 0, 0, 0);
                return LY_EVALID;
            }

            /* remember a new existing case */
            new_case = scase;
        }
    }

    LOG_LOCBACK(1, 0, 0, 0);

    if (old_case && new_case) {
        /* auto-delete old case */
        iter = NULL;
        match = NULL;
        to_del = NULL;
        while ((match = lys_getnext_data(match, *first, &iter, old_case, NULL))) {
            lyd_del_move_root(first, to_del, mod);

            /* free previous node */
            lyd_free_tree(to_del);
            if (diff) {
                /* add into diff */
                LY_CHECK_RET(lyd_val_diff_add(match, LYD_DIFF_OP_DELETE, diff));
            }
            to_del = match;
        }
        lyd_del_move_root(first, to_del, mod);
        lyd_free_tree(to_del);
    }

    return LY_SUCCESS;
}

/**
 * @brief Check whether a schema node can have some default values (true for NP containers as well).
 *
 * @param[in] schema Schema node to check.
 * @return non-zero if yes,
 * @return 0 otherwise.
 */
static int
lyd_val_has_default(const struct lysc_node *schema)
{
    switch (schema->nodetype) {
    case LYS_LEAF:
        if (((struct lysc_node_leaf *)schema)->dflt) {
            return 1;
        }
        break;
    case LYS_LEAFLIST:
        if (((struct lysc_node_leaflist *)schema)->dflts) {
            return 1;
        }
        break;
    case LYS_CONTAINER:
        if (!(schema->flags & LYS_PRESENCE)) {
            return 1;
        }
        break;
    default:
        break;
    }

    return 0;
}

/**
 * @brief Properly delete a node as part of auto-delete validation tasks.
 *
 * @param[in,out] first First sibling, is updated if needed.
 * @param[in] del Node instance to delete.
 * @param[in] mod Module of the siblings, NULL for nested siblings.
 * @param[in,out] node Current iteration node, update it if it is deleted.
 * @param[in,out] diff Validation diff.
 * @return 1 if @p node auto-deleted and updated to its next sibling.
 * @return 0 if @p node was not auto-deleted.
 */
static ly_bool
lyd_validate_autodel_node_del(struct lyd_node **first, struct lyd_node *del, const struct lys_module *mod,
        struct lyd_node **node, struct lyd_node **diff)
{
    struct lyd_node *iter;
    ly_bool node_autodel = 0;

    lyd_del_move_root(first, del, mod);
    if (del == *node) {
        *node = (*node)->next;
        node_autodel = 1;
    }
    if (diff) {
        /* add into diff */
        if ((del->schema->nodetype == LYS_CONTAINER) && !(del->schema->flags & LYS_PRESENCE)) {
            /* we do not want to track NP container changes, but remember any removed children */
            LY_LIST_FOR(lyd_child(del), iter) {
                lyd_val_diff_add(iter, LYD_DIFF_OP_DELETE, diff);
            }
        } else {
            lyd_val_diff_add(del, LYD_DIFF_OP_DELETE, diff);
        }
    }
    lyd_free_tree(del);

    return node_autodel;
}

/**
 * @brief Auto-delete leaf-list default instances to prevent validation errors.
 *
 * @param[in,out] first First sibling to search in, is updated if needed.
 * @param[in,out] node New data node instance to check, is updated if auto-deleted.
 * @param[in] mod Module of the siblings, NULL for nested siblings.
 * @param[in,out] diff Validation diff.
 * @return 1 if @p node auto-deleted and updated to its next sibling.
 * @return 0 if @p node was not auto-deleted.
 */
static ly_bool
lyd_validate_autodel_leaflist_dflt(struct lyd_node **first, struct lyd_node **node, const struct lys_module *mod,
        struct lyd_node **diff)
{
    const struct lysc_node *schema;
    struct lyd_node *iter, *next;
    ly_bool found = 0, node_autodel = 0;

    assert((*node)->flags & LYD_NEW);

    schema = (*node)->schema;
    assert(schema->nodetype == LYS_LEAFLIST);

    /* check whether there is any explicit instance */
    LYD_LIST_FOR_INST(*first, schema, iter) {
        if (!(iter->flags & LYD_DEFAULT)) {
            found = 1;
            break;
        }
    }
    if (!found) {
        /* no explicit instance, keep defaults as they are */
        return 0;
    }

    LYD_LIST_FOR_INST_SAFE(*first, schema, next, iter) {
        if (iter->flags & LYD_DEFAULT) {
            /* default instance found, remove it */
            if (lyd_validate_autodel_node_del(first, iter, mod, node, diff)) {
                node_autodel = 1;
            }
        }
    }

    return node_autodel;
}

/**
 * @brief Auto-delete container or leaf default instances to prevent validation errors.
 *
 * @param[in,out] first First sibling to search in, is updated if needed.
 * @param[in,out] node New data node instance to check, is updated if auto-deleted.
 * @param[in] mod Module of the siblings, NULL for nested siblings.
 * @param[in,out] diff Validation diff.
 * @return 1 if @p node auto-deleted and updated to its next sibling.
 * @return 0 if @p node was not auto-deleted.
 */
static ly_bool
lyd_validate_autodel_cont_leaf_dflt(struct lyd_node **first, struct lyd_node **node, const struct lys_module *mod,
        struct lyd_node **diff)
{
    const struct lysc_node *schema;
    struct lyd_node *iter, *next;
    ly_bool found = 0, node_autodel = 0;

    assert((*node)->flags & LYD_NEW);

    schema = (*node)->schema;
    assert(schema->nodetype & (LYS_LEAF | LYS_CONTAINER));

    /* check whether there is any explicit instance */
    LYD_LIST_FOR_INST(*first, schema, iter) {
        if (!(iter->flags & LYD_DEFAULT)) {
            found = 1;
            break;
        }
    }

    if (found) {
        /* remove all default instances */
        LYD_LIST_FOR_INST_SAFE(*first, schema, next, iter) {
            if (iter->flags & LYD_DEFAULT) {
                /* default instance, remove it */
                if (lyd_validate_autodel_node_del(first, iter, mod, node, diff)) {
                    node_autodel = 1;
                }
            }
        }
    } else {
        /* remove a single old default instance, if any */
        LYD_LIST_FOR_INST(*first, schema, iter) {
            if ((iter->flags & LYD_DEFAULT) && !(iter->flags & LYD_NEW)) {
                /* old default instance, remove it */
                if (lyd_validate_autodel_node_del(first, iter, mod, node, diff)) {
                    node_autodel = 1;
                }
                break;
            }
        }
    }

    return node_autodel;
}

/**
 * @brief Auto-delete leftover default nodes of deleted cases (that have no existing explicit data).
 *
 * @param[in,out] first First sibling to search in, is updated if needed.
 * @param[in,out] node Default data node instance to check.
 * @param[in] mod Module of the siblings, NULL for nested siblings.
 * @param[in,out] diff Validation diff.
 * @return 1 if @p node auto-deleted and updated to its next sibling.
 * @return 0 if @p node was not auto-deleted.
 */
static ly_bool
lyd_validate_autodel_case_dflt(struct lyd_node **first, struct lyd_node **node, const struct lys_module *mod,
        struct lyd_node **diff)
{
    const struct lysc_node *schema;
    struct lysc_node_choice *choic;
    struct lyd_node *iter = NULL;
    const struct lysc_node *slast = NULL;
    ly_bool node_autodel = 0;

    assert((*node)->flags & LYD_DEFAULT);

    schema = (*node)->schema;

    if (!schema->parent || (schema->parent->nodetype != LYS_CASE)) {
        /* the default node is not a descendant of a case */
        return 0;
    }

    choic = (struct lysc_node_choice *)schema->parent->parent;
    assert(choic->nodetype == LYS_CHOICE);

    if (choic->dflt && (choic->dflt == (struct lysc_node_case *)schema->parent)) {
        /* data of a default case, keep them */
        return 0;
    }

    /* try to find an explicit node of the case */
    while ((iter = lys_getnext_data(iter, *first, &slast, schema->parent, NULL))) {
        if (!(iter->flags & LYD_DEFAULT)) {
            break;
        }
    }

    if (!iter) {
        /* there are only default nodes of the case meaning it does not exist and neither should any default nodes
         * of the case, remove this one default node */
        if (lyd_validate_autodel_node_del(first, *node, mod, node, diff)) {
            node_autodel = 1;
        }
    }

    return node_autodel;
}

/**
 * @brief Validate new siblings in choices, recursively for nested choices.
 *
 * @param[in,out] first First sibling.
 * @param[in] sparent Schema parent of the siblings, NULL for top-level siblings.
 * @param[in] mod Module of the siblings, NULL for nested siblings.
 * @param[in,out] diff Validation diff.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_choice_r(struct lyd_node **first, const struct lysc_node *sparent, const struct lys_module *mod,
        struct lyd_node **diff)
{
    const struct lysc_node *snode = NULL;

    while (*first && (snode = lys_getnext(snode, sparent, mod ? mod->compiled : NULL, LYS_GETNEXT_WITHCHOICE))) {
        /* check case duplicites */
        if (snode->nodetype == LYS_CHOICE) {
            LY_CHECK_RET(lyd_validate_cases(first, mod, (struct lysc_node_choice *)snode, diff));

            /* check for nested choice */
            LY_CHECK_RET(lyd_validate_choice_r(first, snode, mod, diff));
        }
    }

    return LY_SUCCESS;
}

LY_ERR
lyd_validate_new(struct lyd_node **first, const struct lysc_node *sparent, const struct lys_module *mod,
        struct lyd_node **diff)
{
    LY_ERR r;
    struct lyd_node *node;
    const struct lysc_node *last_dflt_schema = NULL;

    assert(first && (sparent || mod));

    /* validate choices */
    LY_CHECK_RET(lyd_validate_choice_r(first, sparent, mod, diff));

    node = *first;
    while (node) {
        if (!node->schema || (mod && (lyd_owner_module(node) != mod))) {
            /* opaque node or all top-level data from this module checked */
            break;
        }

        if (!(node->flags & (LYD_NEW | LYD_DEFAULT))) {
            /* check only new and default nodes */
            node = node->next;
            continue;
        }

        if (lyd_val_has_default(node->schema) && (node->schema != last_dflt_schema) && (node->flags & LYD_NEW)) {
            /* remove old default(s) of the new node if an explicit instance exists */
            last_dflt_schema = node->schema;
            if (node->schema->nodetype == LYS_LEAFLIST) {
                if (lyd_validate_autodel_leaflist_dflt(first, &node, mod, diff)) {
                    continue;
                }
            } else {
                if (lyd_validate_autodel_cont_leaf_dflt(first, &node, mod, diff)) {
                    continue;
                }
            }
        }

        if (node->flags & LYD_NEW) {
            /* then check new node instance duplicities */
            LOG_LOCSET(NULL, node, NULL, NULL);
            r = lyd_validate_duplicates(*first, node);
            LOG_LOCBACK(0, 1, 0, 0);
            LY_CHECK_RET(r);

            /* this node is valid */
            node->flags &= ~LYD_NEW;
        }

        if (node->flags & LYD_DEFAULT) {
            /* remove leftover default nodes from a no-longer existing case */
            if (lyd_validate_autodel_case_dflt(first, &node, mod, diff)) {
                continue;
            }
        }

        /* next iter */
        node = node->next;
    }

    return LY_SUCCESS;
}

/**
 * @brief Evaluate any "when" conditions of a non-existent data node with existing parent.
 *
 * @param[in] first First data sibling of the non-existing node.
 * @param[in] parent Data parent of the non-existing node.
 * @param[in] snode Schema node of the non-existing node.
 * @param[out] disabled First when that evaluated false, if any.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_dummy_when(const struct lyd_node *first, const struct lyd_node *parent, const struct lysc_node *snode,
        const struct lysc_when **disabled)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyd_node *tree, *dummy = NULL;
    uint32_t xp_opts;

    /* find root */
    if (parent) {
        tree = (struct lyd_node *)parent;
        while (tree->parent) {
            tree = lyd_parent(tree);
        }
        tree = lyd_first_sibling(tree);
    } else {
        /* is the first sibling from the same module, but may not be the actual first */
        tree = lyd_first_sibling(first);
    }

    /* create dummy opaque node */
    ret = lyd_new_opaq((struct lyd_node *)parent, snode->module->ctx, snode->name, NULL, NULL, snode->module->name, &dummy);
    LY_CHECK_GOTO(ret, cleanup);

    /* connect it if needed */
    if (!parent) {
        if (first) {
            lyd_insert_sibling((struct lyd_node *)first, dummy, &tree);
        } else {
            assert(!tree);
            tree = dummy;
        }
    }

    /* explicitly specified accesible tree */
    if (snode->flags & LYS_CONFIG_W) {
        xp_opts = LYXP_ACCESS_TREE_CONFIG;
    } else {
        xp_opts = LYXP_ACCESS_TREE_ALL;
    }

    /* evaluate all when */
    ret = lyd_validate_node_when(tree, dummy, snode, xp_opts, disabled);
    if (ret == LY_EINCOMPLETE) {
        /* all other when must be resolved by now */
        LOGINT(snode->module->ctx);
        ret = LY_EINT;
        goto cleanup;
    } else if (ret) {
        /* error */
        goto cleanup;
    }

cleanup:
    lyd_free_tree(dummy);
    return ret;
}

/**
 * @brief Validate mandatory node existence.
 *
 * @param[in] first First sibling to search in.
 * @param[in] parent Data parent.
 * @param[in] snode Schema node to validate.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_mandatory(const struct lyd_node *first, const struct lyd_node *parent, const struct lysc_node *snode)
{
    const struct lysc_when *disabled;

    if (snode->nodetype == LYS_CHOICE) {
        /* some data of a choice case exist */
        if (lys_getnext_data(NULL, first, NULL, snode, NULL)) {
            return LY_SUCCESS;
        }
    } else {
        assert(snode->nodetype & (LYS_LEAF | LYS_CONTAINER | LYD_NODE_ANY));

        if (!lyd_find_sibling_val(first, snode, NULL, 0, NULL)) {
            /* data instance found */
            return LY_SUCCESS;
        }
    }

    disabled = NULL;
    if (lysc_has_when(snode)) {
        /* if there are any when conditions, they must be true for a validation error */
        LY_CHECK_RET(lyd_validate_dummy_when(first, parent, snode, &disabled));
    }

    if (!disabled) {
        /* node instance not found */
        if (snode->nodetype == LYS_CHOICE) {
            LOGVAL_APPTAG(snode->module->ctx, "missing-choice", LY_VCODE_NOMAND_CHOIC, snode->name);
        } else {
            LOGVAL(snode->module->ctx, LY_VCODE_NOMAND, snode->name);
        }
        return LY_EVALID;
    }

    return LY_SUCCESS;
}

/**
 * @brief Validate min/max-elements constraints, if any.
 *
 * @param[in] first First sibling to search in.
 * @param[in] parent Data parent.
 * @param[in] snode Schema node to validate.
 * @param[in] min Minimum number of elements, 0 for no restriction.
 * @param[in] max Max number of elements, 0 for no restriction.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_minmax(const struct lyd_node *first, const struct lyd_node *parent, const struct lysc_node *snode,
        uint32_t min, uint32_t max)
{
    uint32_t count = 0;
    struct lyd_node *iter;
    const struct lysc_when *disabled;
    ly_bool invalid_instance = 0;

    assert(min || max);

    LYD_LIST_FOR_INST(first, snode, iter) {
        ++count;

        if (min && (count == min)) {
            /* satisfied */
            min = 0;
            if (!max) {
                /* nothing more to check */
                break;
            }
        }
        if (max && (count > max)) {
            /* not satisifed */
            LOG_LOCSET(NULL, iter, NULL, NULL);
            invalid_instance = 1;
            break;
        }
    }

    if (min) {
        assert(count < min);

        disabled = NULL;
        if (lysc_has_when(snode)) {
            /* if there are any when conditions, they must be true for a validation error */
            LY_CHECK_RET(lyd_validate_dummy_when(first, parent, snode, &disabled));
        }

        if (!disabled) {
            LOGVAL_APPTAG(snode->module->ctx, "too-few-elements", LY_VCODE_NOMIN, snode->name);
            goto failure;
        }
    } else if (max && (count > max)) {
        LOGVAL_APPTAG(snode->module->ctx, "too-many-elements", LY_VCODE_NOMAX, snode->name);
        goto failure;
    }

    return LY_SUCCESS;

failure:
    LOG_LOCBACK(0, invalid_instance, 0, 0);
    return LY_EVALID;
}

/**
 * @brief Find node referenced by a list unique statement.
 *
 * @param[in] uniq_leaf Unique leaf to find.
 * @param[in] list List instance to use for the search.
 * @return Found leaf,
 * @return NULL if no leaf found.
 */
static struct lyd_node *
lyd_val_uniq_find_leaf(const struct lysc_node_leaf *uniq_leaf, const struct lyd_node *list)
{
    struct lyd_node *node;
    const struct lysc_node *iter;
    size_t depth = 0, i;

    /* get leaf depth */
    for (iter = &uniq_leaf->node; iter && (iter != list->schema); iter = lysc_data_parent(iter)) {
        ++depth;
    }

    node = (struct lyd_node *)list;
    while (node && depth) {
        /* find schema node with this depth */
        for (i = depth - 1, iter = &uniq_leaf->node; i; iter = lysc_data_parent(iter)) {
            --i;
        }

        /* find iter instance in children */
        assert(iter->nodetype & (LYS_CONTAINER | LYS_LEAF));
        lyd_find_sibling_val(lyd_child(node), iter, NULL, 0, &node);
        --depth;
    }

    return node;
}

/**
 * @brief Callback for comparing 2 list unique leaf values.
 *
 * Implementation of ::lyht_value_equal_cb.
 *
 * @param[in] cb_data 0 to compare all uniques, n to compare only n-th unique.
 */
static ly_bool
lyd_val_uniq_list_equal(void *val1_p, void *val2_p, ly_bool UNUSED(mod), void *cb_data)
{
    struct ly_ctx *ctx;
    struct lysc_node_list *slist;
    struct lyd_node *diter, *first, *second;
    struct lyd_value *val1, *val2;
    char *path1, *path2, *uniq_str, *ptr;
    LY_ARRAY_COUNT_TYPE u, v, action;

    assert(val1_p && val2_p);

    first = *((struct lyd_node **)val1_p);
    second = *((struct lyd_node **)val2_p);
    action = (uintptr_t)cb_data;

    assert(first && (first->schema->nodetype == LYS_LIST));
    assert(second && (second->schema == first->schema));

    ctx = first->schema->module->ctx;

    slist = (struct lysc_node_list *)first->schema;

    /* compare unique leaves */
    if (action > 0) {
        u = action - 1;
        if (u < LY_ARRAY_COUNT(slist->uniques)) {
            goto uniquecheck;
        }
    }
    LY_ARRAY_FOR(slist->uniques, u) {
uniquecheck:
        LY_ARRAY_FOR(slist->uniques[u], v) {
            /* first */
            diter = lyd_val_uniq_find_leaf(slist->uniques[u][v], first);
            if (diter) {
                val1 = &((struct lyd_node_term *)diter)->value;
            } else {
                /* use default value */
                val1 = slist->uniques[u][v]->dflt;
            }

            /* second */
            diter = lyd_val_uniq_find_leaf(slist->uniques[u][v], second);
            if (diter) {
                val2 = &((struct lyd_node_term *)diter)->value;
            } else {
                /* use default value */
                val2 = slist->uniques[u][v]->dflt;
            }

            if (!val1 || !val2 || val1->realtype->plugin->compare(val1, val2)) {
                /* values differ or either one is not set */
                break;
            }
        }
        if (v && (v == LY_ARRAY_COUNT(slist->uniques[u]))) {
            /* all unique leafs are the same in this set, create this nice error */
            path1 = lyd_path(first, LYD_PATH_STD, NULL, 0);
            path2 = lyd_path(second, LYD_PATH_STD, NULL, 0);

            /* use buffer to rebuild the unique string */
#define UNIQ_BUF_SIZE 1024
            uniq_str = malloc(UNIQ_BUF_SIZE);
            uniq_str[0] = '\0';
            ptr = uniq_str;
            LY_ARRAY_FOR(slist->uniques[u], v) {
                if (v) {
                    strcpy(ptr, " ");
                    ++ptr;
                }
                ptr = lysc_path_until((struct lysc_node *)slist->uniques[u][v], &slist->node, LYSC_PATH_LOG,
                        ptr, UNIQ_BUF_SIZE - (ptr - uniq_str));
                if (!ptr) {
                    /* path will be incomplete, whatever */
                    break;
                }

                ptr += strlen(ptr);
            }
            LOG_LOCSET(NULL, second, NULL, NULL);
            LOGVAL_APPTAG(ctx, "data-not-unique", LY_VCODE_NOUNIQ, uniq_str, path1, path2);
            LOG_LOCBACK(0, 1, 0, 0);

            free(path1);
            free(path2);
            free(uniq_str);
#undef UNIQ_BUF_SIZE

            return 1;
        }

        if (action > 0) {
            /* done */
            return 0;
        }
    }

    return 0;
}

/**
 * @brief Validate list unique leaves.
 *
 * @param[in] first First sibling to search in.
 * @param[in] snode Schema node to validate.
 * @param[in] uniques List unique arrays to validate.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_unique(const struct lyd_node *first, const struct lysc_node *snode, const struct lysc_node_leaf ***uniques)
{
    const struct lyd_node *diter;
    struct ly_set *set;
    LY_ARRAY_COUNT_TYPE u, v, x = 0;
    LY_ERR ret = LY_SUCCESS;
    uint32_t hash, i;
    size_t key_len;
    ly_bool dyn;
    const void *hash_key;
    void *cb_data;
    struct hash_table **uniqtables = NULL;
    struct lyd_value *val;
    struct ly_ctx *ctx = snode->module->ctx;

    assert(uniques);

    /* get all list instances */
    LY_CHECK_RET(ly_set_new(&set));
    LY_LIST_FOR(first, diter) {
        if (diter->schema == snode) {
            ret = ly_set_add(set, (void *)diter, 1, NULL);
            LY_CHECK_GOTO(ret, cleanup);
        }
    }

    if (set->count == 2) {
        /* simple comparison */
        if (lyd_val_uniq_list_equal(&set->objs[0], &set->objs[1], 0, (void *)0)) {
            /* instance duplication */
            ret = LY_EVALID;
            goto cleanup;
        }
    } else if (set->count > 2) {
        /* use hashes for comparison */
        uniqtables = malloc(LY_ARRAY_COUNT(uniques) * sizeof *uniqtables);
        LY_CHECK_ERR_GOTO(!uniqtables, LOGMEM(ctx); ret = LY_EMEM, cleanup);
        x = LY_ARRAY_COUNT(uniques);
        for (v = 0; v < x; v++) {
            cb_data = (void *)(uintptr_t)(v + 1L);
            uniqtables[v] = lyht_new(lyht_get_fixed_size(set->count), sizeof(struct lyd_node *),
                    lyd_val_uniq_list_equal, cb_data, 0);
            LY_CHECK_ERR_GOTO(!uniqtables[v], LOGMEM(ctx); ret = LY_EMEM, cleanup);
        }

        for (i = 0; i < set->count; i++) {
            /* loop for unique - get the hash for the instances */
            for (u = 0; u < x; u++) {
                val = NULL;
                for (v = hash = 0; v < LY_ARRAY_COUNT(uniques[u]); v++) {
                    diter = lyd_val_uniq_find_leaf(uniques[u][v], set->objs[i]);
                    if (diter) {
                        val = &((struct lyd_node_term *)diter)->value;
                    } else {
                        /* use default value */
                        val = uniques[u][v]->dflt;
                    }
                    if (!val) {
                        /* unique item not present nor has default value */
                        break;
                    }

                    /* get hash key */
                    hash_key = val->realtype->plugin->print(NULL, val, LY_VALUE_LYB, NULL, &dyn, &key_len);
                    hash = dict_hash_multi(hash, hash_key, key_len);
                    if (dyn) {
                        free((void *)hash_key);
                    }
                }
                if (!val) {
                    /* skip this list instance since its unique set is incomplete */
                    continue;
                }

                /* finish the hash value */
                hash = dict_hash_multi(hash, NULL, 0);

                /* insert into the hashtable */
                ret = lyht_insert(uniqtables[u], &set->objs[i], hash, NULL);
                if (ret == LY_EEXIST) {
                    /* instance duplication */
                    ret = LY_EVALID;
                }
                LY_CHECK_GOTO(ret != LY_SUCCESS, cleanup);
            }
        }
    }

cleanup:
    ly_set_free(set, NULL);
    for (v = 0; v < x; v++) {
        if (!uniqtables[v]) {
            /* failed when allocating uniquetables[j], following j are not allocated */
            break;
        }
        lyht_free(uniqtables[v], NULL);
    }
    free(uniqtables);

    return ret;
}

/**
 * @brief Validate data siblings based on generic schema node restrictions, recursively for schema-only nodes.
 *
 * @param[in] first First sibling to search in.
 * @param[in] parent Data parent.
 * @param[in] sparent Schema parent of the nodes to check.
 * @param[in] mod Module of the nodes to check.
 * @param[in] val_opts Validation options, see @ref datavalidationoptions.
 * @param[in] int_opts Internal parser options.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_siblings_schema_r(const struct lyd_node *first, const struct lyd_node *parent,
        const struct lysc_node *sparent, const struct lysc_module *mod, uint32_t val_opts, uint32_t int_opts)
{
    LY_ERR ret = LY_SUCCESS;
    const struct lysc_node *snode = NULL, *scase;
    struct lysc_node_list *slist;
    struct lysc_node_leaflist *sllist;
    uint32_t getnext_opts;

    getnext_opts = LYS_GETNEXT_WITHCHOICE | (int_opts & LYD_INTOPT_REPLY ? LYS_GETNEXT_OUTPUT : 0);

    /* disabled nodes are skipped by lys_getnext */
    while ((snode = lys_getnext(snode, sparent, mod, getnext_opts))) {
        if ((val_opts & LYD_VALIDATE_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
            continue;
        }

        LOG_LOCSET(snode, NULL, NULL, NULL);

        /* check min-elements and max-elements */
        if (snode->nodetype == LYS_LIST) {
            slist = (struct lysc_node_list *)snode;
            if (slist->min || slist->max) {
                ret = lyd_validate_minmax(first, parent, snode, slist->min, slist->max);
                LY_CHECK_GOTO(ret, error);
            }
        } else if (snode->nodetype == LYS_LEAFLIST) {
            sllist = (struct lysc_node_leaflist *)snode;
            if (sllist->min || sllist->max) {
                ret = lyd_validate_minmax(first, parent, snode, sllist->min, sllist->max);
                LY_CHECK_GOTO(ret, error);
            }

        } else if (snode->flags & LYS_MAND_TRUE) {
            /* check generic mandatory existence */
            ret = lyd_validate_mandatory(first, parent, snode);
            LY_CHECK_GOTO(ret, error);
        }

        /* check unique */
        if (snode->nodetype == LYS_LIST) {
            slist = (struct lysc_node_list *)snode;
            if (slist->uniques) {
                ret = lyd_validate_unique(first, snode, (const struct lysc_node_leaf ***)slist->uniques);
                LY_CHECK_GOTO(ret, error);
            }
        }

        if (snode->nodetype == LYS_CHOICE) {
            /* find the existing case, if any */
            LY_LIST_FOR(lysc_node_child(snode), scase) {
                if (lys_getnext_data(NULL, first, NULL, scase, NULL)) {
                    /* validate only this case */
                    ret = lyd_validate_siblings_schema_r(first, parent, scase, mod, val_opts, int_opts);
                    LY_CHECK_GOTO(ret, error);
                    break;
                }
            }
        }

        LOG_LOCBACK(1, 0, 0, 0);
    }

    return LY_SUCCESS;

error:
    LOG_LOCBACK(1, 0, 0, 0);
    return ret;
}

/**
 * @brief Validate obsolete nodes, only warnings are printed.
 *
 * @param[in] node Node to check.
 */
static void
lyd_validate_obsolete(const struct lyd_node *node)
{
    const struct lysc_node *snode;

    snode = node->schema;
    do {
        if (snode->flags & LYS_STATUS_OBSLT) {
            LOGWRN(snode->module->ctx, "Obsolete schema node \"%s\" instantiated in data.", snode->name);
            break;
        }

        snode = snode->parent;
    } while (snode && (snode->nodetype & (LYS_CHOICE | LYS_CASE)));
}

/**
 * @brief Validate must conditions of a data node.
 *
 * @param[in] node Node to validate.
 * @param[in] int_opts Internal parser options.
 * @param[in] xpath_options Additional XPath options to use.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_must(const struct lyd_node *node, uint32_t int_opts, uint32_t xpath_options)
{
    LY_ERR ret;
    struct lyxp_set xp_set;
    struct lysc_must *musts;
    const struct lyd_node *tree;
    const struct lysc_node *schema;
    const char *emsg, *eapptag;
    LY_ARRAY_COUNT_TYPE u;

    assert((int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY)) != (LYD_INTOPT_RPC | LYD_INTOPT_REPLY));
    assert((int_opts & (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY)) != (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY));

    if (node->schema->nodetype & (LYS_ACTION | LYS_RPC)) {
        if (int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_ACTION)) {
            schema = &((struct lysc_node_action *)node->schema)->input.node;
        } else if (int_opts & LYD_INTOPT_REPLY) {
            schema = &((struct lysc_node_action *)node->schema)->output.node;
        } else {
            LOGINT_RET(LYD_CTX(node));
        }
    } else {
        schema = node->schema;
    }
    musts = lysc_node_musts(schema);
    if (!musts) {
        /* no must to evaluate */
        return LY_SUCCESS;
    }

    /* find first top-level node */
    for (tree = node; tree->parent; tree = lyd_parent(tree)) {}
    tree = lyd_first_sibling(tree);

    LY_ARRAY_FOR(musts, u) {
        memset(&xp_set, 0, sizeof xp_set);

        /* evaluate must */
        ret = lyxp_eval(LYD_CTX(node), musts[u].cond, node->schema->module, LY_VALUE_SCHEMA_RESOLVED,
                musts[u].prefixes, node, node, tree, NULL, &xp_set, LYXP_SCHEMA | xpath_options);
        if (ret == LY_EINCOMPLETE) {
            LOGINT_RET(LYD_CTX(node));
        } else if (ret) {
            return ret;
        }

        /* check the result */
        lyxp_set_cast(&xp_set, LYXP_SET_BOOLEAN);
        if (!xp_set.val.bln) {
            /* use specific error information */
            emsg = musts[u].emsg;
            eapptag = musts[u].eapptag ? musts[u].eapptag : "must-violation";
            if (emsg) {
                LOGVAL_APPTAG(LYD_CTX(node), eapptag, LYVE_DATA, "%s", emsg);
            } else {
                LOGVAL_APPTAG(LYD_CTX(node), eapptag, LY_VCODE_NOMUST, musts[u].cond->expr);
            }
            return LY_EVALID;
        }
    }

    return LY_SUCCESS;
}

/**
 * @brief Perform all remaining validation tasks, the data tree must be final when calling this function.
 *
 * @param[in] first First sibling.
 * @param[in] parent Data parent.
 * @param[in] sparent Schema parent of the siblings, NULL for top-level siblings.
 * @param[in] mod Module of the siblings, NULL for nested siblings.
 * @param[in] val_opts Validation options (@ref datavalidationoptions).
 * @param[in] int_opts Internal parser options.
 * @param[in] must_xp_opts Additional XPath options to use for evaluating "must".
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_final_r(struct lyd_node *first, const struct lyd_node *parent, const struct lysc_node *sparent,
        const struct lys_module *mod, uint32_t val_opts, uint32_t int_opts, uint32_t must_xp_opts)
{
    LY_ERR r;
    const char *innode;
    struct lyd_node *next = NULL, *node;

    /* validate all restrictions of nodes themselves */
    LY_LIST_FOR_SAFE(first, next, node) {
        if (node->flags & LYD_EXT) {
            /* ext instance data should have already been validated */
            continue;
        }

        LOG_LOCSET(node->schema, node, NULL, NULL);

        /* opaque data */
        if (!node->schema) {
            r = lyd_parse_opaq_error(node);
            LOG_LOCBACK(0, 1, 0, 0);
            return r;
        }

        if (!node->parent && mod && (lyd_owner_module(node) != mod)) {
            /* all top-level data from this module checked */
            LOG_LOCBACK(1, 1, 0, 0);
            break;
        }

        /* no state/input/output/op data */
        innode = NULL;
        if ((val_opts & LYD_VALIDATE_NO_STATE) && (node->schema->flags & LYS_CONFIG_R)) {
            innode = "state";
        } else if ((int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_ACTION)) && (node->schema->flags & LYS_IS_OUTPUT)) {
            innode = "output";
        } else if ((int_opts & LYD_INTOPT_REPLY) && (node->schema->flags & LYS_IS_INPUT)) {
            innode = "input";
        } else if (!(int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY)) && (node->schema->nodetype == LYS_RPC)) {
            innode = "rpc";
        } else if (!(int_opts & (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY)) && (node->schema->nodetype == LYS_ACTION)) {
            innode = "action";
        } else if (!(int_opts & LYD_INTOPT_NOTIF) && (node->schema->nodetype == LYS_NOTIF)) {
            innode = "notification";
        }
        if (innode) {
            LOGVAL(LYD_CTX(node), LY_VCODE_UNEXPNODE, innode, node->schema->name);
            LOG_LOCBACK(1, 1, 0, 0);
            return LY_EVALID;
        }

        /* obsolete data */
        lyd_validate_obsolete(node);

        /* node's musts */
        if ((r = lyd_validate_must(node, int_opts, must_xp_opts))) {
            LOG_LOCBACK(1, 1, 0, 0);
            return r;
        }

        /* node value was checked by plugins */

        /* next iter */
        LOG_LOCBACK(1, 1, 0, 0);
    }

    /* validate schema-based restrictions */
    LY_CHECK_RET(lyd_validate_siblings_schema_r(first, parent, sparent, mod ? mod->compiled : NULL, val_opts, int_opts));

    LY_LIST_FOR(first, node) {
        if (!node->parent && mod && (lyd_owner_module(node) != mod)) {
            /* all top-level data from this module checked */
            break;
        }

        /* validate all children recursively */
        LY_CHECK_RET(lyd_validate_final_r(lyd_child(node), node, node->schema, NULL, val_opts, int_opts, must_xp_opts));

        /* set default for containers */
        lyd_cont_set_dflt(node);
    }

    return LY_SUCCESS;
}

/**
 * @brief Validate extension instance data by storing it in its unres set.
 *
 * @param[in] sibling First sibling with ::LYD_EXT flag, all the following ones are expected to have it, too.
 * @param[in,out] ext_val Set with parsed extension instance data to validate.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_nested_ext(struct lyd_node *sibling, struct ly_set *ext_val)
{
    struct lyd_node *node;
    struct lyd_ctx_ext_val *ext_v;
    struct lysc_ext_instance *nested_exts, *ext = NULL;
    LY_ARRAY_COUNT_TYPE u;

    /* check of basic assumptions */
    if (!sibling->parent || !sibling->parent->schema) {
        LOGINT_RET(LYD_CTX(sibling));
    }
    LY_LIST_FOR(sibling, node) {
        if (!(node->flags & LYD_EXT)) {
            LOGINT_RET(LYD_CTX(sibling));
        }
    }

    /* try to find the extension instance */
    nested_exts = sibling->parent->schema->exts;
    LY_ARRAY_FOR(nested_exts, u) {
        if (nested_exts[u].def->plugin->validate) {
            if (ext) {
                /* more extension instances with validate callback */
                LOGINT_RET(LYD_CTX(sibling));
            }
            ext = &nested_exts[u];
        }
    }
    if (!ext) {
        /* no extension instance with validate callback */
        LOGINT_RET(LYD_CTX(sibling));
    }

    /* store for validation */
    ext_v = malloc(sizeof *ext_v);
    LY_CHECK_ERR_RET(!ext_v, LOGMEM(LYD_CTX(sibling)), LY_EMEM);
    ext_v->ext = ext;
    ext_v->sibling = sibling;
    LY_CHECK_RET(ly_set_add(ext_val, ext_v, 1, NULL));

    return LY_SUCCESS;
}

LY_ERR
lyd_validate_node_ext(struct lyd_node *node, struct ly_set *ext_node)
{
    struct lyd_ctx_ext_node *ext_n;
    struct lysc_ext_instance *exts;
    LY_ARRAY_COUNT_TYPE u;

    /* try to find a relevant extension instance with node callback */
    exts = node->schema->exts;
    LY_ARRAY_FOR(exts, u) {
        if (exts[u].def->plugin && exts[u].def->plugin->node) {
            /* store for validation */
            ext_n = malloc(sizeof *ext_n);
            LY_CHECK_ERR_RET(!ext_n, LOGMEM(LYD_CTX(node)), LY_EMEM);
            ext_n->ext = &exts[u];
            ext_n->node = node;
            LY_CHECK_RET(ly_set_add(ext_node, ext_n, 1, NULL));
        }
    }

    return LY_SUCCESS;
}

/**
 * @brief Validate the whole data subtree.
 *
 * @param[in] root Subtree root.
 * @param[in,out] node_when Set for nodes with when conditions.
 * @param[in,out] node_types Set for unres node types.
 * @param[in,out] meta_types Set for unres metadata types.
 * @param[in,out] ext_node Set with nodes with extensions to validate.
 * @param[in,out] ext_val Set for parsed extension data to validate.
 * @param[in] impl_opts Implicit options, see @ref implicitoptions.
 * @param[in,out] diff Validation diff.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_subtree(struct lyd_node *root, struct ly_set *node_when, struct ly_set *node_types,
        struct ly_set *meta_types, struct ly_set *ext_node, struct ly_set *ext_val, uint32_t impl_opts,
        struct lyd_node **diff)
{
    const struct lyd_meta *meta;
    const struct lysc_type *type;
    struct lyd_node *node;

    LYD_TREE_DFS_BEGIN(root, node) {
        if (node->flags & LYD_EXT) {
            /* validate using the extension instance callback */
            return lyd_validate_nested_ext(node, ext_val);
        }

        if (!node->schema) {
            /* do not validate opaque nodes */
            goto next_node;
        }

        LY_LIST_FOR(node->meta, meta) {
            lyplg_ext_get_storage(meta->annotation, LY_STMT_TYPE, sizeof type, (const void **)&type);
            if (type->plugin->validate) {
                /* metadata type resolution */
                LY_CHECK_RET(ly_set_add(meta_types, (void *)meta, 1, NULL));
            }
        }

        if ((node->schema->nodetype & LYD_NODE_TERM) && ((struct lysc_node_leaf *)node->schema)->type->plugin->validate) {
            /* node type resolution */
            LY_CHECK_RET(ly_set_add(node_types, (void *)node, 1, NULL));
        } else if (node->schema->nodetype & LYD_NODE_INNER) {
            /* new node validation, autodelete */
            LY_CHECK_RET(lyd_validate_new(lyd_node_child_p(node), node->schema, NULL, diff));

            /* add nested defaults */
            LY_CHECK_RET(lyd_new_implicit_r(node, lyd_node_child_p(node), NULL, NULL, NULL, NULL, NULL, impl_opts, diff));
        }

        if (lysc_has_when(node->schema)) {
            /* when evaluation */
            LY_CHECK_RET(ly_set_add(node_when, (void *)node, 1, NULL));
        }

        /* store for ext instance node validation, if needed */
        LY_CHECK_RET(lyd_validate_node_ext(node, ext_node));

next_node:
        LYD_TREE_DFS_END(root, node);
    }

    return LY_SUCCESS;
}

LY_ERR
lyd_validate(struct lyd_node **tree, const struct lys_module *module, const struct ly_ctx *ctx, uint32_t val_opts,
        ly_bool validate_subtree, struct ly_set *node_when_p, struct ly_set *node_types_p, struct ly_set *meta_types_p,
        struct ly_set *ext_node_p, struct ly_set *ext_val_p, struct lyd_node **diff)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyd_node *first, *next, **first2, *iter;
    const struct lys_module *mod;
    struct ly_set node_types = {0}, meta_types = {0}, node_when = {0}, ext_node = {0}, ext_val = {0};
    uint32_t i = 0;

    assert(tree && ctx);
    assert((node_when_p && node_types_p && meta_types_p && ext_node_p && ext_val_p) ||
            (!node_when_p && !node_types_p && !meta_types_p && !ext_node_p && !ext_val_p));

    if (!node_when_p) {
        node_when_p = &node_when;
        node_types_p = &node_types;
        meta_types_p = &meta_types;
        ext_node_p = &ext_node;
        ext_val_p = &ext_val;
    }

    next = *tree;
    while (1) {
        if (val_opts & LYD_VALIDATE_PRESENT) {
            mod = lyd_data_next_module(&next, &first);
        } else {
            mod = lyd_mod_next_module(next, module, ctx, &i, &first);
        }
        if (!mod) {
            break;
        }
        if (!first || (first == *tree)) {
            /* make sure first2 changes are carried to tree */
            first2 = tree;
        } else {
            first2 = &first;
        }

        /* validate new top-level nodes of this module, autodelete */
        ret = lyd_validate_new(first2, NULL, mod, diff);
        LY_CHECK_GOTO(ret, cleanup);

        /* add all top-level defaults for this module, if going to validate subtree, do not add into unres sets
         * (lyd_validate_subtree() adds all the nodes in that case) */
        ret = lyd_new_implicit_r(NULL, first2, NULL, mod, validate_subtree ? NULL : node_when_p,
                validate_subtree ? NULL : node_types_p, validate_subtree ? NULL : ext_node_p,
                (val_opts & LYD_VALIDATE_NO_STATE) ? LYD_IMPLICIT_NO_STATE : 0, diff);
        LY_CHECK_GOTO(ret, cleanup);

        /* our first module node pointer may no longer be the first */
        first = *first2;
        lyd_first_module_sibling(&first, mod);
        if (!first || (first == *tree)) {
            first2 = tree;
        } else {
            first2 = &first;
        }

        if (validate_subtree) {
            /* process nested nodes */
            LY_LIST_FOR(*first2, iter) {
                if (lyd_owner_module(iter) != mod) {
                    break;
                }

                ret = lyd_validate_subtree(iter, node_when_p, node_types_p, meta_types_p, ext_node_p, ext_val_p,
                        (val_opts & LYD_VALIDATE_NO_STATE) ? LYD_IMPLICIT_NO_STATE : 0, diff);
                LY_CHECK_GOTO(ret, cleanup);
            }
        }

        /* finish incompletely validated terminal values/attributes and when conditions */
        ret = lyd_validate_unres(first2, mod, LYD_TYPE_DATA_YANG, node_when_p, 0, node_types_p, meta_types_p,
                ext_node_p, ext_val_p, val_opts, diff);
        LY_CHECK_GOTO(ret, cleanup);

        /* perform final validation that assumes the data tree is final */
        ret = lyd_validate_final_r(*first2, NULL, NULL, mod, val_opts, 0, 0);
        LY_CHECK_GOTO(ret, cleanup);
    }

cleanup:
    ly_set_erase(&node_when, NULL);
    ly_set_erase(&node_types, NULL);
    ly_set_erase(&meta_types, NULL);
    ly_set_erase(&ext_node, free);
    ly_set_erase(&ext_val, free);
    return ret;
}

LIBYANG_API_DEF LY_ERR
lyd_validate_all(struct lyd_node **tree, const struct ly_ctx *ctx, uint32_t val_opts, struct lyd_node **diff)
{
    LY_CHECK_ARG_RET(NULL, tree, *tree || ctx, LY_EINVAL);
    LY_CHECK_CTX_EQUAL_RET(*tree ? LYD_CTX(*tree) : NULL, ctx, LY_EINVAL);
    if (!ctx) {
        ctx = LYD_CTX(*tree);
    }
    if (diff) {
        *diff = NULL;
    }

    return lyd_validate(tree, NULL, ctx, val_opts, 1, NULL, NULL, NULL, NULL, NULL, diff);
}

LIBYANG_API_DEF LY_ERR
lyd_validate_module(struct lyd_node **tree, const struct lys_module *module, uint32_t val_opts, struct lyd_node **diff)
{
    LY_CHECK_ARG_RET(NULL, tree, *tree || module, LY_EINVAL);
    LY_CHECK_CTX_EQUAL_RET(*tree ? LYD_CTX(*tree) : NULL, module ? module->ctx : NULL, LY_EINVAL);
    if (diff) {
        *diff = NULL;
    }

    return lyd_validate(tree, module, (*tree) ? LYD_CTX(*tree) : module->ctx, val_opts, 1, NULL, NULL, NULL, NULL, NULL,
            diff);
}

/**
 * @brief Find nodes for merging an operation into data tree for validation.
 *
 * @param[in] op_tree Full operation data tree.
 * @param[in] op_node Operation node itself.
 * @param[in] tree Data tree to be merged into.
 * @param[out] op_subtree Operation subtree to merge.
 * @param[out] tree_sibling Data tree sibling to merge next to, is set if @p tree_parent is NULL.
 * @param[out] tree_parent Data tree parent to merge into, is set if @p tree_sibling is NULL.
 */
static void
lyd_val_op_merge_find(const struct lyd_node *op_tree, const struct lyd_node *op_node, const struct lyd_node *tree,
        struct lyd_node **op_subtree, struct lyd_node **tree_sibling, struct lyd_node **tree_parent)
{
    const struct lyd_node *tree_iter, *op_iter;
    struct lyd_node *match = NULL;
    uint32_t i, cur_depth, op_depth;

    *op_subtree = NULL;
    *tree_sibling = NULL;
    *tree_parent = NULL;

    /* learn op depth (top-level being depth 0) */
    op_depth = 0;
    for (op_iter = op_node; op_iter != op_tree; op_iter = lyd_parent(op_iter)) {
        ++op_depth;
    }

    /* find where to merge op */
    tree_iter = tree;
    cur_depth = op_depth;
    while (cur_depth && tree_iter) {
        /* find op iter in tree */
        lyd_find_sibling_first(tree_iter, op_iter, &match);
        if (!match) {
            break;
        }

        /* move tree_iter */
        tree_iter = lyd_child(match);

        /* move depth */
        --cur_depth;

        /* find next op parent */
        op_iter = op_node;
        for (i = 0; i < cur_depth; ++i) {
            op_iter = lyd_parent(op_iter);
        }
    }

    assert(op_iter);
    *op_subtree = (struct lyd_node *)op_iter;
    if (!tree || tree_iter) {
        /* there is no tree whatsoever or this is the last found sibling */
        *tree_sibling = (struct lyd_node *)tree_iter;
    } else {
        /* matching parent was found but it has no children to insert next to */
        assert(match);
        *tree_parent = match;
    }
}

/**
 * @brief Validate an RPC/action request, reply, or notification.
 *
 * @param[in] op_tree Full operation data tree.
 * @param[in] op_node Operation node itself.
 * @param[in] dep_tree Tree to be used for validating references from the operation subtree.
 * @param[in] int_opts Internal parser options.
 * @param[in] data_type Type of validated data.
 * @param[in] validate_subtree Whether subtree was already validated (as part of data parsing) or not (separate validation).
 * @param[in] node_when_p Set of nodes with when conditions, if NULL a local set is used.
 * @param[in] node_types_p Set of unres node types, if NULL a local set is used.
 * @param[in] meta_types_p Set of unres metadata types, if NULL a local set is used.
 * @param[in] ext_node_p Set of unres nodes with extensions to validate, if NULL a local set is used.
 * @param[in] ext_val_p Set of parsed extension data to validate, if NULL a local set is used.
 * @param[out] diff Optional diff with any changes made by the validation.
 * @return LY_SUCCESS on success.
 * @return LY_ERR error on error.
 */
static LY_ERR
_lyd_validate_op(struct lyd_node *op_tree, struct lyd_node *op_node, const struct lyd_node *dep_tree, enum lyd_type data_type,
        uint32_t int_opts, ly_bool validate_subtree, struct ly_set *node_when_p, struct ly_set *node_types_p,
        struct ly_set *meta_types_p,  struct ly_set *ext_node_p, struct ly_set *ext_val_p, struct lyd_node **diff)
{
    LY_ERR rc = LY_SUCCESS;
    struct lyd_node *tree_sibling, *tree_parent, *op_subtree, *op_parent, *op_sibling_before, *op_sibling_after, *child;
    struct ly_set node_types = {0}, meta_types = {0}, node_when = {0}, ext_node = {0}, ext_val = {0};

    assert(op_tree && op_node);
    assert((node_when_p && node_types_p && meta_types_p && ext_node_p && ext_val_p) ||
            (!node_when_p && !node_types_p && !meta_types_p && !ext_node_p && !ext_val_p));

    if (!node_when_p) {
        node_when_p = &node_when;
        node_types_p = &node_types;
        meta_types_p = &meta_types;
        ext_node_p = &ext_node;
        ext_val_p = &ext_val;
    }

    /* merge op_tree into dep_tree */
    lyd_val_op_merge_find(op_tree, op_node, dep_tree, &op_subtree, &tree_sibling, &tree_parent);
    op_sibling_before = op_subtree->prev->next ? op_subtree->prev : NULL;
    op_sibling_after = op_subtree->next;
    op_parent = lyd_parent(op_subtree);

    lyd_unlink_tree(op_subtree);
    lyd_insert_node(tree_parent, &tree_sibling, op_subtree, 0);
    if (!dep_tree) {
        dep_tree = tree_sibling;
    }

    LOG_LOCSET(NULL, op_node, NULL, NULL);

    if (int_opts & LYD_INTOPT_REPLY) {
        /* add output children defaults */
        rc = lyd_new_implicit_r(op_node, lyd_node_child_p(op_node), NULL, NULL, node_when_p, node_types_p,
                ext_node_p, LYD_IMPLICIT_OUTPUT, diff);
        LY_CHECK_GOTO(rc, cleanup);

        if (validate_subtree) {
            /* skip validating the operation itself, go to children directly */
            LY_LIST_FOR(lyd_child(op_node), child) {
                rc = lyd_validate_subtree(child, node_when_p, node_types_p, meta_types_p, ext_node_p, ext_val_p, 0, diff);
                LY_CHECK_GOTO(rc, cleanup);
            }
        }
    } else {
        if (validate_subtree) {
            /* prevalidate whole operation subtree */
            rc = lyd_validate_subtree(op_node, node_when_p, node_types_p, meta_types_p, ext_node_p, ext_val_p, 0, diff);
            LY_CHECK_GOTO(rc, cleanup);
        }
    }

    /* finish incompletely validated terminal values/attributes and when conditions on the full tree,
     * account for unresolved 'when' that may appear in the non-validated dependency data tree */
    LY_CHECK_GOTO(rc = lyd_validate_unres((struct lyd_node **)&dep_tree, NULL, data_type, node_when_p, LYXP_IGNORE_WHEN,
            node_types_p, meta_types_p, ext_node_p, ext_val_p, 0, diff), cleanup);

    /* perform final validation of the operation/notification */
    lyd_validate_obsolete(op_node);
    LY_CHECK_GOTO(rc = lyd_validate_must(op_node, int_opts, LYXP_IGNORE_WHEN), cleanup);

    /* final validation of all the descendants */
    rc = lyd_validate_final_r(lyd_child(op_node), op_node, op_node->schema, NULL, 0, int_opts, LYXP_IGNORE_WHEN);
    LY_CHECK_GOTO(rc, cleanup);

cleanup:
    LOG_LOCBACK(0, 1, 0, 0);

    /* restore operation tree */
    lyd_unlink_tree(op_subtree);
    if (op_sibling_before) {
        lyd_insert_after_node(op_sibling_before, op_subtree);
    } else if (op_sibling_after) {
        lyd_insert_before_node(op_sibling_after, op_subtree);
    } else if (op_parent) {
        lyd_insert_node(op_parent, NULL, op_subtree, 0);
    }

    ly_set_erase(&node_when, NULL);
    ly_set_erase(&node_types, NULL);
    ly_set_erase(&meta_types, NULL);
    ly_set_erase(&ext_node, free);
    ly_set_erase(&ext_val, free);
    return rc;
}

LIBYANG_API_DEF LY_ERR
lyd_validate_op(struct lyd_node *op_tree, const struct lyd_node *dep_tree, enum lyd_type data_type, struct lyd_node **diff)
{
    struct lyd_node *op_node;
    uint32_t int_opts;
    struct ly_set ext_val = {0};
    LY_ERR rc;

    LY_CHECK_ARG_RET(NULL, op_tree, !dep_tree || !dep_tree->parent, (data_type == LYD_TYPE_RPC_YANG) ||
            (data_type == LYD_TYPE_NOTIF_YANG) || (data_type == LYD_TYPE_REPLY_YANG), LY_EINVAL);
    if (diff) {
        *diff = NULL;
    }
    if (data_type == LYD_TYPE_RPC_YANG) {
        int_opts = LYD_INTOPT_RPC | LYD_INTOPT_ACTION;
    } else if (data_type == LYD_TYPE_NOTIF_YANG) {
        int_opts = LYD_INTOPT_NOTIF;
    } else {
        int_opts = LYD_INTOPT_REPLY;
    }

    if (op_tree->schema && (op_tree->schema->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))) {
        /* we have the operation/notification, adjust the pointers */
        op_node = op_tree;
        while (op_tree->parent) {
            op_tree = lyd_parent(op_tree);
        }
    } else {
        /* find the operation/notification */
        while (op_tree->parent) {
            op_tree = lyd_parent(op_tree);
        }
        LYD_TREE_DFS_BEGIN(op_tree, op_node) {
            if (!op_node->schema) {
                return lyd_parse_opaq_error(op_node);
            } else if (op_node->flags & LYD_EXT) {
                /* fully validate the rest using the extension instance callback */
                LY_CHECK_RET(lyd_validate_nested_ext(op_node, &ext_val));
                rc = lyd_validate_unres((struct lyd_node **)&dep_tree, NULL, data_type, NULL, 0, NULL, NULL, NULL,
                        &ext_val, 0, diff);
                ly_set_erase(&ext_val, free);
                return rc;
            }

            if ((int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_ACTION | LYD_INTOPT_REPLY)) &&
                    (op_node->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
                break;
            } else if ((int_opts & LYD_INTOPT_NOTIF) && (op_node->schema->nodetype == LYS_NOTIF)) {
                break;
            }
            LYD_TREE_DFS_END(op_tree, op_node);
        }
    }

    if (int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_ACTION | LYD_INTOPT_REPLY)) {
        if (!op_node || !(op_node->schema->nodetype & (LYS_RPC | LYS_ACTION))) {
            LOGERR(LYD_CTX(op_tree), LY_EINVAL, "No RPC/action to validate found.");
            return LY_EINVAL;
        }
    } else {
        if (!op_node || (op_node->schema->nodetype != LYS_NOTIF)) {
            LOGERR(LYD_CTX(op_tree), LY_EINVAL, "No notification to validate found.");
            return LY_EINVAL;
        }
    }

    /* validate */
    return _lyd_validate_op(op_tree, op_node, dep_tree, data_type, int_opts, 1, NULL, NULL, NULL, NULL, NULL, diff);
}
