/**
 * @file validation.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief Validation
 *
 * Copyright (c) 2019 - 2023 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"

/**
 * @brief Check validation error taking into account multi-error validation.
 *
 * @param[in] r Local return value.
 * @param[in] err_cmd Command to perform on any error.
 * @param[in] val_opts Validation options.
 * @param[in] label Label to go to on fatal error.
 */
#define LY_VAL_ERR_GOTO(r, err_cmd, val_opts, label) \
        if (r) { \
            err_cmd; \
            if ((r != LY_EVALID) || !(val_opts & LYD_VALIDATE_MULTI_ERROR)) { \
                goto label; \
            } \
        }

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 r;
    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);
            r = 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(r);

            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] val_opts Validation options.
 * @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 val_opts,
        uint32_t xpath_options, struct ly_set *node_types, struct lyd_node **diff)
{
    LY_ERR rc = LY_SUCCESS, 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 */
                        r = lyd_val_diff_add(node, LYD_DIFF_OP_DELETE, diff);
                        LY_CHECK_ERR_GOTO(r, rc = r, 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)) {
                                r = ly_set_rm_index(node_types, idx, NULL);
                                LY_CHECK_ERR_GOTO(r, rc = r, error);
                            }
                            LYD_TREE_DFS_END(node, elem);
                        }
                    }

                    /* free */
                    lyd_free_tree(node);
                } else if (val_opts & LYD_VALIDATE_OPERATIONAL) {
                    /* only a warning */
                    LOGWRN(LYD_CTX(node), "When condition \"%s\" not satisfied.", disabled->cond->expr);
                } else {
                    /* invalid data */
                    LOGVAL(LYD_CTX(node), LY_VCODE_NOWHEN, disabled->cond->expr);
                    r = LY_EVALID;
                    LY_VAL_ERR_GOTO(r, rc = r, val_opts, 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 */
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, error);
        }

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

    return rc;

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 r, rc = 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 */
            r = ext_v->ext->def->plugin->validate(ext_v->ext, ext_v->sibling, *tree, data_type, val_opts, diff);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

            /* 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 */
            r = ext_n->ext->def->plugin->node(ext_n->ext, ext_n->node, val_opts);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

            /* 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;
            r = lyd_validate_unres_when(tree, mod, node_when, val_opts, when_xp_opts, node_types, diff);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

            /* 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);
            r = lyd_value_validate_incomplete(LYD_CTX(node), type, &node->value, &node->node, *tree);
            LOG_LOCBACK(0, 1, 0, 0);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

            /* 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);
            r = lyd_value_validate_incomplete(LYD_CTX(meta->parent), type, &meta->value, meta->parent, *tree);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

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

cleanup:
    return rc;
}

/**
 * @brief Validate instance duplication.
 *
 * @param[in] first First sibling to search in.
 * @param[in] node Data node instance to check.
 * @param[in] val_opts Validation options.
 * @return LY_ERR value.
 */
static LY_ERR
lyd_validate_duplicates(const struct lyd_node *first, const struct lyd_node *node, uint32_t val_opts)
{
    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) {
        if ((node->schema->nodetype & (LYS_LIST | LYS_LEAFLIST)) && (val_opts & LYD_VALIDATE_OPERATIONAL)) {
            /* only a warning */
            LOG_LOCSET(NULL, node, NULL, NULL);
            LOGWRN(node->schema->module->ctx, "Duplicate instance of \"%s\".", node->schema->name);
            LOG_LOCBACK(0, 1, 0, 0);
        } else {
            LOG_LOCSET(NULL, node, NULL, NULL);
            LOGVAL(node->schema->module->ctx, LY_VCODE_DUP, node->schema->name);
            LOG_LOCBACK(0, 1, 0, 0);
            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] val_opts Validation options.
 * @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,
        uint32_t val_opts, struct lyd_node **diff)
{
    LY_ERR r, rc = LY_SUCCESS;
    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) {
            r = lyd_validate_cases(first, mod, (struct lysc_node_choice *)snode, diff);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

            /* check for nested choice */
            r = lyd_validate_choice_r(first, snode, mod, val_opts, diff);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
        }
    }

cleanup:
    return rc;
}

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

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

    /* validate choices */
    r = lyd_validate_choice_r(first, sparent, mod, val_opts, diff);
    LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

    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 */
            r = lyd_validate_duplicates(*first, node, val_opts);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

            /* 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;
    }

cleanup:
    return rc;
}

/**
 * @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 rc = 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 */
    rc = lyd_new_opaq((struct lyd_node *)parent, snode->module->ctx, snode->name, NULL, NULL, snode->module->name, &dummy);
    LY_CHECK_GOTO(rc, 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 */
    rc = lyd_validate_node_when(tree, dummy, snode, xp_opts, disabled);
    if (rc == LY_EINCOMPLETE) {
        /* all other when must be resolved by now */
        LOGINT(snode->module->ctx);
        rc = LY_EINT;
        goto cleanup;
    } else if (rc) {
        /* error */
        goto cleanup;
    }

cleanup:
    lyd_free_tree(dummy);
    return rc;
}

/**
 * @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.
 * @param[in] val_opts Validation options.
 * @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,
        uint32_t val_opts)
{
    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) {
        if (val_opts & LYD_VALIDATE_OPERATIONAL) {
            /* only a warning */
            LOG_LOCSET(parent ? NULL : snode, parent, NULL, NULL);
            if (snode->nodetype == LYS_CHOICE) {
                LOGWRN(snode->module->ctx, "Mandatory choice \"%s\" data do not exist.", snode->name);
            } else {
                LOGWRN(snode->module->ctx, "Mandatory node \"%s\" instance does not exist.", snode->name);
            }
            LOG_LOCBACK(parent ? 0 : 1, parent ? 1 : 0, 0, 0);
        } else {
            /* node instance not found */
            LOG_LOCSET(parent ? NULL : snode, parent, NULL, NULL);
            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);
            }
            LOG_LOCBACK(parent ? 0 : 1, parent ? 1 : 0, 0, 0);
            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.
 * @param[in] val_opts Validation options.
 * @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 val_opts)
{
    uint32_t count = 0;
    struct lyd_node *iter;
    const struct lysc_when *disabled;

    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 */
            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) {
            /* satisfied */
            min = 0;
        }
    }
    if (max && (count <= max)) {
        /* satisfied */
        max = 0;
    }

    if (min) {
        if (val_opts & LYD_VALIDATE_OPERATIONAL) {
            /* only a warning */
            LOG_LOCSET(snode, NULL, NULL, NULL);
            LOGWRN(snode->module->ctx, "Too few \"%s\" instances.", snode->name);
            LOG_LOCBACK(1, 0, 0, 0);
        } else {
            LOG_LOCSET(snode, NULL, NULL, NULL);
            LOGVAL_APPTAG(snode->module->ctx, "too-few-elements", LY_VCODE_NOMIN, snode->name);
            LOG_LOCBACK(1, 0, 0, 0);
            return LY_EVALID;
        }
    } else if (max) {
        if (val_opts & LYD_VALIDATE_OPERATIONAL) {
            /* only a warning */
            LOG_LOCSET(NULL, iter, NULL, NULL);
            LOGWRN(snode->module->ctx, "Too many \"%s\" instances.", snode->name);
            LOG_LOCBACK(0, 1, 0, 0);
        } else {
            LOG_LOCSET(NULL, iter, NULL, NULL);
            LOGVAL_APPTAG(snode->module->ctx, "too-many-elements", LY_VCODE_NOMAX, snode->name);
            LOG_LOCBACK(0, 1, 0, 0);
            return LY_EVALID;
        }
    }
    return LY_SUCCESS;
}

/**
 * @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 Unique list validation callback argument.
 */
struct lyd_val_uniq_arg {
    LY_ARRAY_COUNT_TYPE action; /**< Action to perform - 0 to compare all uniques, n to compare only n-th unique. */
    uint32_t val_opts;          /**< Validation options. */
};

/**
 * @brief Callback for comparing 2 list unique leaf values.
 *
 * Implementation of ::lyht_value_equal_cb.
 */
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;
    struct lyd_val_uniq_arg *arg = cb_data;
    const uint32_t uniq_err_msg_size = 1024;

    assert(val1_p && val2_p);

    first = *((struct lyd_node **)val1_p);
    second = *((struct lyd_node **)val2_p);

    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 (arg->action > 0) {
        u = arg->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 leaves 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 */
            uniq_str = malloc(uniq_err_msg_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_err_msg_size - (ptr - uniq_str));
                if (!ptr) {
                    /* path will be incomplete, whatever */
                    break;
                }

                ptr += strlen(ptr);
            }
            LOG_LOCSET(NULL, second, NULL, NULL);
            if (arg->val_opts & LYD_VALIDATE_OPERATIONAL) {
                /* only a warning */
                LOGWRN(ctx, "Unique data leaf(s) \"%s\" not satisfied in \"%s\" and \"%s\".", uniq_str, path1, path2);
            } else {
                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);

            if (!(arg->val_opts & LYD_VALIDATE_OPERATIONAL)) {
                return 1;
            }
        }

        if (arg->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.
 * @param[in] val_opts Validation options.
 * @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,
        uint32_t val_opts)
{
    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;
    struct lyd_val_uniq_arg arg, *args = NULL;
    struct ly_ht **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 */
        arg.action = 0;
        arg.val_opts = val_opts;
        if (lyd_val_uniq_list_equal(&set->objs[0], &set->objs[1], 0, &arg)) {
            /* instance duplication */
            ret = LY_EVALID;
            goto cleanup;
        }
    } else if (set->count > 2) {
        /* use hashes for comparison */
        uniqtables = malloc(LY_ARRAY_COUNT(uniques) * sizeof *uniqtables);
        args = malloc(LY_ARRAY_COUNT(uniques) * sizeof *args);
        LY_CHECK_ERR_GOTO(!uniqtables || !args, LOGMEM(ctx); ret = LY_EMEM, cleanup);
        x = LY_ARRAY_COUNT(uniques);
        for (v = 0; v < x; v++) {
            args[v].action = v + 1;
            args[v].val_opts = val_opts;
            uniqtables[v] = lyht_new(lyht_get_fixed_size(set->count), sizeof(struct lyd_node *),
                    lyd_val_uniq_list_equal, &args[v], 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 = lyht_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 = lyht_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);
    free(args);

    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 r, rc = 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;
        }

        /* check min-elements and max-elements */
        if (snode->nodetype == LYS_LIST) {
            slist = (struct lysc_node_list *)snode;
            if (slist->min || slist->max) {
                r = lyd_validate_minmax(first, parent, snode, slist->min, slist->max, val_opts);
                LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
            }
        } else if (snode->nodetype == LYS_LEAFLIST) {
            sllist = (struct lysc_node_leaflist *)snode;
            if (sllist->min || sllist->max) {
                r = lyd_validate_minmax(first, parent, snode, sllist->min, sllist->max, val_opts);
                LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
            }

        } else if (snode->flags & LYS_MAND_TRUE) {
            /* check generic mandatory existence */
            r = lyd_validate_mandatory(first, parent, snode, val_opts);
            LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
        }

        /* check unique */
        if (snode->nodetype == LYS_LIST) {
            slist = (struct lysc_node_list *)snode;
            if (slist->uniques) {
                r = lyd_validate_unique(first, snode, (const struct lysc_node_leaf ***)slist->uniques, val_opts);
                LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
            }
        }

        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 */
                    r = lyd_validate_siblings_schema_r(first, parent, scase, mod, val_opts, int_opts);
                    LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
                    break;
                }
            }
        }
    }

cleanup:
    return rc;
}

/**
 * @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) {
            LOG_LOCSET(NULL, node, NULL, NULL);
            LOGWRN(snode->module->ctx, "Obsolete schema node \"%s\" instantiated in data.", snode->name);
            LOG_LOCBACK(0, 1, 0, 0);
            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] val_opts Validation options.
 * @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 val_opts, uint32_t int_opts, uint32_t xpath_options)
{
    LY_ERR r, rc = LY_SUCCESS;
    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 */
        r = 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 (r == LY_EINCOMPLETE) {
            LOGINT(LYD_CTX(node));
            r = LY_EINT;
        }
        LY_CHECK_ERR_GOTO(r, rc = r, cleanup);

        /* check the result */
        lyxp_set_cast(&xp_set, LYXP_SET_BOOLEAN);
        if (!xp_set.val.bln) {
            if (val_opts & LYD_VALIDATE_OPERATIONAL) {
                /* only a warning */
                emsg = musts[u].emsg;
                LOG_LOCSET(NULL, node, NULL, NULL);
                if (emsg) {
                    LOGWRN(LYD_CTX(node), "%s", emsg);
                } else {
                    LOGWRN(LYD_CTX(node), "Must condition \"%s\" not satisfied.", musts[u].cond->expr);
                }
                LOG_LOCBACK(0, 1, 0, 0);
            } else {
                /* use specific error information */
                emsg = musts[u].emsg;
                eapptag = musts[u].eapptag ? musts[u].eapptag : "must-violation";
                LOG_LOCSET(NULL, node, NULL, NULL);
                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);
                }
                LOG_LOCBACK(0, 1, 0, 0);
                r = LY_EVALID;
                LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
            }
        }
    }

cleanup:
    return rc;
}

/**
 * @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, rc = LY_SUCCESS;
    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;
        }

        /* opaque data */
        if (!node->schema) {
            r = lyd_parse_opaq_error(node);
            goto next_iter;
        }

        if (!node->parent && mod && (lyd_owner_module(node) != mod)) {
            /* all top-level data from this module checked */
            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) {
            LOG_LOCSET(NULL, node, NULL, NULL);
            LOGVAL(LYD_CTX(node), LY_VCODE_UNEXPNODE, innode, node->schema->name);
            LOG_LOCBACK(0, 1, 0, 0);
            r = LY_EVALID;
            goto next_iter;
        }

        /* obsolete data */
        lyd_validate_obsolete(node);

        /* node's musts */
        if ((r = lyd_validate_must(node, val_opts, int_opts, must_xp_opts))) {
            goto next_iter;
        }

        /* node value was checked by plugins */

next_iter:
        LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
    }

    /* validate schema-based restrictions */
    r = lyd_validate_siblings_schema_r(first, parent, sparent, mod ? mod->compiled : NULL, val_opts, int_opts);
    LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

    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 */
        r = lyd_validate_final_r(lyd_child(node), node, node->schema, NULL, val_opts, int_opts, must_xp_opts);
        LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

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

cleanup:
    return rc;
}

/**
 * @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] val_opts Validation options.
 * @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 val_opts,
        struct lyd_node **diff)
{
    LY_ERR r, rc = LY_SUCCESS;
    const struct lyd_meta *meta;
    const struct lysc_type *type;
    struct lyd_node *node;
    uint32_t impl_opts;

    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 */
                r = ly_set_add(meta_types, (void *)meta, 1, NULL);
                LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
            }
        }

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

            /* add nested defaults */
            impl_opts = 0;
            if (val_opts & LYD_VALIDATE_NO_STATE) {
                impl_opts |= LYD_IMPLICIT_NO_STATE;
            }
            if (val_opts & LYD_VALIDATE_NO_DEFAULTS) {
                impl_opts |= LYD_IMPLICIT_NO_DEFAULTS;
            }
            r = lyd_new_implicit_r(node, lyd_node_child_p(node), NULL, NULL, NULL, NULL, NULL, impl_opts, diff);
            LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
        }

        if (lysc_has_when(node->schema)) {
            /* when evaluation */
            r = ly_set_add(node_when, (void *)node, 1, NULL);
            LY_CHECK_ERR_GOTO(r, rc = r, cleanup);
        }

        /* store for ext instance node validation, if needed */
        r = lyd_validate_node_ext(node, ext_node);
        LY_CHECK_ERR_GOTO(r, rc = r, cleanup);

next_node:
        LYD_TREE_DFS_END(root, node);
    }

cleanup:
    return rc;
}

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 r, rc = 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, impl_opts;

    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 */
        r = lyd_validate_new(first2, NULL, mod, val_opts, diff);
        LY_VAL_ERR_GOTO(r, rc = r, val_opts, 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) */
        impl_opts = 0;
        if (val_opts & LYD_VALIDATE_NO_STATE) {
            impl_opts |= LYD_IMPLICIT_NO_STATE;
        }
        if (val_opts & LYD_VALIDATE_NO_DEFAULTS) {
            impl_opts |= LYD_IMPLICIT_NO_DEFAULTS;
        }
        r = 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, impl_opts, diff);
        LY_CHECK_ERR_GOTO(r, rc = r, 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;
                }

                r = lyd_validate_subtree(iter, node_when_p, node_types_p, meta_types_p, ext_node_p, ext_val_p,
                        val_opts, diff);
                LY_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);
            }
        }

        /* finish incompletely validated terminal values/attributes and when conditions */
        r = 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_VAL_ERR_GOTO(r, rc = r, val_opts, cleanup);

        /* perform final validation that assumes the data tree is final */
        r = lyd_validate_final_r(*first2, NULL, NULL, mod, val_opts, 0, 0);
        LY_VAL_ERR_GOTO(r, rc = r, val_opts, 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 rc;
}

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

    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, 0, 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:
    /* restore operation tree */
    lyd_unlink_tree(op_subtree);
    if (op_sibling_before) {
        lyd_insert_after_node(op_sibling_before, op_subtree);
        lyd_insert_hash(op_subtree);
    } else if (op_sibling_after) {
        lyd_insert_before_node(op_sibling_after, op_subtree);
        lyd_insert_hash(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);
}
