/**
 * @file printer_lyb.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief LYB printer for libyang data structure
 *
 * Copyright (c) 2020 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#include "lyb.h"

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

#include "common.h"
#include "compat.h"
#include "context.h"
#include "hash_table.h"
#include "log.h"
#include "out.h"
#include "out_internal.h"
#include "printer_data.h"
#include "printer_internal.h"
#include "set.h"
#include "tree.h"
#include "tree_data.h"
#include "tree_data_internal.h"
#include "tree_edit.h"
#include "tree_schema.h"
#include "tree_schema_internal.h"
#include "xml.h"

static LY_ERR lyb_print_siblings(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx);

/**
 * @brief Hash table equal callback for checking hash equality only.
 *
 * Implementation of ::lyht_value_equal_cb.
 */
static ly_bool
lyb_hash_equal_cb(void *UNUSED(val1_p), void *UNUSED(val2_p), ly_bool UNUSED(mod), void *UNUSED(cb_data))
{
    /* for this purpose, if hash matches, the value does also, we do not want 2 values to have the same hash */
    return 1;
}

/**
 * @brief Hash table equal callback for checking value pointer equality only.
 *
 * Implementation of ::lyht_value_equal_cb.
 */
static ly_bool
lyb_ptr_equal_cb(void *val1_p, void *val2_p, ly_bool UNUSED(mod), void *UNUSED(cb_data))
{
    struct lysc_node *val1 = *(struct lysc_node **)val1_p;
    struct lysc_node *val2 = *(struct lysc_node **)val2_p;

    if (val1 == val2) {
        return 1;
    }
    return 0;
}

/**
 * @brief Check that sibling collision hash is safe to insert into hash table.
 *
 * @param[in] ht Hash table.
 * @param[in] sibling Hashed sibling.
 * @param[in] ht_col_id Sibling hash collision ID.
 * @param[in] compare_col_id Last collision ID to compare with.
 * @return LY_SUCCESS when the whole hash sequence does not collide,
 * @return LY_EEXIST when the whole hash sequence sollides.
 */
static LY_ERR
lyb_hash_sequence_check(struct hash_table *ht, struct lysc_node *sibling, LYB_HASH ht_col_id, LYB_HASH compare_col_id)
{
    struct lysc_node **col_node;

    /* get the first node inserted with last hash col ID ht_col_id */
    if (lyht_find(ht, &sibling, lyb_get_hash(sibling, ht_col_id), (void **)&col_node)) {
        /* there is none. valid situation */
        return LY_SUCCESS;
    }

    lyht_set_cb(ht, lyb_ptr_equal_cb);
    do {
        int64_t j;
        for (j = (int64_t)compare_col_id; j > -1; --j) {
            if (lyb_get_hash(sibling, j) != lyb_get_hash(*col_node, j)) {
                /* one non-colliding hash */
                break;
            }
        }
        if (j == -1) {
            /* all whole hash sequences of nodes inserted with last hash col ID compare_col_id collide */
            lyht_set_cb(ht, lyb_hash_equal_cb);
            return LY_EEXIST;
        }

        /* get next node inserted with last hash col ID ht_col_id */
    } while (!lyht_find_next(ht, col_node, lyb_get_hash(*col_node, ht_col_id), (void **)&col_node));

    lyht_set_cb(ht, lyb_hash_equal_cb);
    return LY_SUCCESS;
}

/**
 * @brief Hash all the siblings and add them also into a separate hash table.
 *
 * @param[in] sibling Any sibling in all the siblings on one level.
 * @param[out] ht_p Created hash table.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_hash_siblings(struct lysc_node *sibling, struct hash_table **ht_p)
{
    struct hash_table *ht;
    const struct lysc_node *parent;
    const struct lys_module *mod;
    LYB_HASH i;
    uint32_t getnext_opts;

    ht = lyht_new(1, sizeof(struct lysc_node *), lyb_hash_equal_cb, NULL, 1);
    LY_CHECK_ERR_RET(!ht, LOGMEM(sibling->module->ctx), LY_EMEM);

    getnext_opts = 0;
    if (sibling->flags & LYS_IS_OUTPUT) {
        getnext_opts = LYS_GETNEXT_OUTPUT;
    }

    parent = lysc_data_parent(sibling);
    mod = sibling->module;

    sibling = NULL;
    while ((sibling = (struct lysc_node *)lys_getnext(sibling, parent, mod->compiled, getnext_opts))) {
        /* find the first non-colliding hash (or specifically non-colliding hash sequence) */
        for (i = 0; i < LYB_HASH_BITS; ++i) {
            /* check that we are not colliding with nodes inserted with a lower collision ID than ours */
            int64_t j;
            for (j = (int64_t)i - 1; j > -1; --j) {
                if (lyb_hash_sequence_check(ht, sibling, (LYB_HASH)j, i)) {
                    break;
                }
            }
            if (j > -1) {
                /* some check failed, we must use a higher collision ID */
                continue;
            }

            /* try to insert node with the current collision ID */
            if (!lyht_insert_with_resize_cb(ht, &sibling, lyb_get_hash(sibling, i), lyb_ptr_equal_cb, NULL)) {
                /* success, no collision */
                break;
            }

            /* make sure we really cannot insert it with this hash col ID (meaning the whole hash sequence is colliding) */
            if (i && !lyb_hash_sequence_check(ht, sibling, i, i)) {
                /* it can be inserted after all, even though there is already a node with the same last collision ID */
                lyht_set_cb(ht, lyb_ptr_equal_cb);
                if (lyht_insert(ht, &sibling, lyb_get_hash(sibling, i), NULL)) {
                    LOGINT(sibling->module->ctx);
                    lyht_set_cb(ht, lyb_hash_equal_cb);
                    lyht_free(ht);
                    return LY_EINT;
                }
                lyht_set_cb(ht, lyb_hash_equal_cb);
                break;
            }
            /* there is still another colliding schema node with the same hash sequence, try higher collision ID */
        }

        if (i == LYB_HASH_BITS) {
            /* wow */
            LOGINT(sibling->module->ctx);
            lyht_free(ht);
            return LY_EINT;
        }
    }

    /* change val equal callback so that the HT is usable for finding value hashes */
    lyht_set_cb(ht, lyb_ptr_equal_cb);

    *ht_p = ht;
    return LY_SUCCESS;
}

/**
 * @brief Find node hash in a hash table.
 *
 * @param[in] ht Hash table to search in.
 * @param[in] node Node to find.
 * @param[out] hash_p First non-colliding hash found.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_hash_find(struct hash_table *ht, struct lysc_node *node, LYB_HASH *hash_p)
{
    LYB_HASH hash;
    uint32_t i;

    for (i = 0; i < LYB_HASH_BITS; ++i) {
        hash = lyb_get_hash(node, i);
        if (!hash) {
            LOGINT_RET(node->module->ctx);
        }

        if (!lyht_find(ht, &node, hash, NULL)) {
            /* success, no collision */
            break;
        }
    }
    /* cannot happen, we already calculated the hash */
    if (i == LYB_HASH_BITS) {
        LOGINT_RET(node->module->ctx);
    }

    *hash_p = hash;
    return LY_SUCCESS;
}

/**
 * @brief Write LYB data fully handling the metadata.
 *
 * @param[in] out Out structure.
 * @param[in] buf Source buffer.
 * @param[in] count Number of bytes to write.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_write(struct ly_out *out, const uint8_t *buf, size_t count, struct lylyb_ctx *lybctx)
{
    LY_ARRAY_COUNT_TYPE u;
    struct lyd_lyb_sibling *full, *iter;
    size_t to_write;
    uint8_t meta_buf[LYB_META_BYTES];

    while (1) {
        /* check for full data chunks */
        to_write = count;
        full = NULL;
        LY_ARRAY_FOR(lybctx->siblings, u) {
            /* we want the innermost chunks resolved first, so replace previous full chunks */
            if (lybctx->siblings[u].written + to_write >= LYB_SIZE_MAX) {
                /* full chunk, do not write more than allowed */
                to_write = LYB_SIZE_MAX - lybctx->siblings[u].written;
                full = &lybctx->siblings[u];
            }
        }

        if (!full && !count) {
            break;
        }

        /* we are actually writing some data, not just finishing another chunk */
        if (to_write) {
            LY_CHECK_RET(ly_write_(out, (char *)buf, to_write));

            LY_ARRAY_FOR(lybctx->siblings, u) {
                /* increase all written counters */
                lybctx->siblings[u].written += to_write;
                assert(lybctx->siblings[u].written <= LYB_SIZE_MAX);
            }
            /* decrease count/buf */
            count -= to_write;
            buf += to_write;
        }

        if (full) {
            /* write the meta information (inner chunk count and chunk size) */
            meta_buf[0] = full->written & LYB_BYTE_MASK;
            meta_buf[1] = full->inner_chunks & LYB_BYTE_MASK;
            LY_CHECK_RET(ly_write_skipped(out, full->position, (char *)meta_buf, LYB_META_BYTES));

            /* zero written and inner chunks */
            full->written = 0;
            full->inner_chunks = 0;

            /* skip space for another chunk size */
            LY_CHECK_RET(ly_write_skip(out, LYB_META_BYTES, &full->position));

            /* increase inner chunk count */
            for (iter = &lybctx->siblings[0]; iter != full; ++iter) {
                if (iter->inner_chunks == LYB_INCHUNK_MAX) {
                    LOGINT(lybctx->ctx);
                    return LY_EINT;
                }
                ++iter->inner_chunks;
            }
        }
    }

    return LY_SUCCESS;
}

/**
 * @brief Stop the current "siblings" - write its final metadata.
 *
 * @param[in] out Out structure.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_write_stop_siblings(struct ly_out *out, struct lylyb_ctx *lybctx)
{
    uint8_t meta_buf[LYB_META_BYTES];

    /* write the meta chunk information */
    meta_buf[0] = LYB_LAST_SIBLING(lybctx).written & LYB_BYTE_MASK;
    meta_buf[1] = LYB_LAST_SIBLING(lybctx).inner_chunks & LYB_BYTE_MASK;
    LY_CHECK_RET(ly_write_skipped(out, LYB_LAST_SIBLING(lybctx).position, (char *)&meta_buf, LYB_META_BYTES));

    LY_ARRAY_DECREMENT(lybctx->siblings);
    return LY_SUCCESS;
}

/**
 * @brief Start a new "siblings" - skip bytes for its metadata.
 *
 * @param[in] out Out structure.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_write_start_siblings(struct ly_out *out, struct lylyb_ctx *lybctx)
{
    LY_ARRAY_COUNT_TYPE u;

    u = LY_ARRAY_COUNT(lybctx->siblings);
    if (u == lybctx->sibling_size) {
        LY_ARRAY_CREATE_RET(lybctx->ctx, lybctx->siblings, u + LYB_SIBLING_STEP, LY_EMEM);
        lybctx->sibling_size = u + LYB_SIBLING_STEP;
    }

    LY_ARRAY_INCREMENT(lybctx->siblings);
    LYB_LAST_SIBLING(lybctx).written = 0;
    LYB_LAST_SIBLING(lybctx).inner_chunks = 0;

    /* another inner chunk */
    for (u = 0; u < LY_ARRAY_COUNT(lybctx->siblings) - 1; ++u) {
        if (lybctx->siblings[u].inner_chunks == LYB_INCHUNK_MAX) {
            LOGINT(lybctx->ctx);
            return LY_EINT;
        }
        ++lybctx->siblings[u].inner_chunks;
    }

    LY_CHECK_RET(ly_write_skip(out, LYB_META_BYTES, &LYB_LAST_SIBLING(lybctx).position));

    return LY_SUCCESS;
}

/**
 * @brief Write a number.
 *
 * @param[in] num Number to write.
 * @param[in] bytes Actual accessible bytes of @p num.
 * @param[in] out Out structure.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_write_number(uint64_t num, size_t bytes, struct ly_out *out, struct lylyb_ctx *lybctx)
{
    /* correct byte order */
    num = htole64(num);

    return lyb_write(out, (uint8_t *)&num, bytes, lybctx);
}

/**
 * @brief Write a string.
 *
 * @param[in] str String to write.
 * @param[in] str_len Length of @p str.
 * @param[in] with_length Whether to precede the string with its length.
 * @param[in] out Out structure.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_write_string(const char *str, size_t str_len, ly_bool with_length, struct ly_out *out, struct lylyb_ctx *lybctx)
{
    if (!str) {
        str = "";
        LY_CHECK_ERR_RET(str_len, LOGINT(lybctx->ctx), LY_EINT);
    }
    if (!str_len) {
        str_len = strlen(str);
    }

    if (with_length) {
        /* print length on 2 bytes */
        if (str_len > UINT16_MAX) {
            LOGINT(lybctx->ctx);
            return LY_EINT;
        }
        LY_CHECK_RET(lyb_write_number(str_len, 2, out, lybctx));
    }

    LY_CHECK_RET(lyb_write(out, (const uint8_t *)str, str_len, lybctx));

    return LY_SUCCESS;
}

/**
 * @brief Print YANG module info.
 *
 * @param[in] out Out structure.
 * @param[in] mod Module to print.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_model(struct ly_out *out, const struct lys_module *mod, struct lylyb_ctx *lybctx)
{
    uint16_t revision;

    /* model name length and model name */
    if (mod) {
        LY_CHECK_RET(lyb_write_string(mod->name, 0, 1, out, lybctx));
    } else {
        lyb_write_number(0, 2, out, lybctx);
        return LY_SUCCESS;
    }

    /* model revision as XXXX XXXX XXXX XXXX (2B) (year is offset from 2000)
     *                   YYYY YYYM MMMD DDDD */
    revision = 0;
    if (mod && mod->revision) {
        int r = atoi(mod->revision);
        r -= LYB_REV_YEAR_OFFSET;
        r <<= LYB_REV_YEAR_SHIFT;

        revision |= r;

        r = atoi(mod->revision + ly_strlen_const("YYYY-"));
        r <<= LYB_REV_MONTH_SHIFT;

        revision |= r;

        r = atoi(mod->revision + ly_strlen_const("YYYY-MM-"));

        revision |= r;
    }
    LY_CHECK_RET(lyb_write_number(revision, sizeof revision, out, lybctx));

    if (mod) {
        /* fill cached hashes, if not already */
        lyb_cache_module_hash(mod);
    }

    return LY_SUCCESS;
}

/**
 * @brief Print all used YANG modules.
 *
 * @param[in] out Out structure.
 * @param[in] root Data root.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_data_models(struct ly_out *out, const struct lyd_node *root, struct lylyb_ctx *lybctx)
{
    struct ly_set *set;
    LY_ARRAY_COUNT_TYPE u;
    LY_ERR ret = LY_SUCCESS;
    struct lys_module *mod;
    const struct lyd_node *elem, *node;
    uint32_t i;

    LY_CHECK_RET(ly_set_new(&set));

    /* collect all data node modules */
    LY_LIST_FOR(root, elem) {
        LYD_TREE_DFS_BEGIN(elem, node) {
            if (node->schema) {
                mod = node->schema->module;
                ret = ly_set_add(set, mod, 0, NULL);
                LY_CHECK_GOTO(ret, cleanup);

                /* add also their modules deviating or augmenting them */
                LY_ARRAY_FOR(mod->deviated_by, u) {
                    ret = ly_set_add(set, mod->deviated_by[u], 0, NULL);
                    LY_CHECK_GOTO(ret, cleanup);
                }
                LY_ARRAY_FOR(mod->augmented_by, u) {
                    ret = ly_set_add(set, mod->augmented_by[u], 0, NULL);
                    LY_CHECK_GOTO(ret, cleanup);
                }

                /* only top-level nodes are processed */
                LYD_TREE_DFS_continue = 1;
            }

            LYD_TREE_DFS_END(elem, node);
        }
    }

    /* now write module count on 2 bytes */
    LY_CHECK_GOTO(ret = lyb_write_number(set->count, 2, out, lybctx), cleanup);

    /* and all the used models */
    for (i = 0; i < set->count; ++i) {
        LY_CHECK_GOTO(ret = lyb_print_model(out, set->objs[i], lybctx), cleanup);
    }

cleanup:
    ly_set_free(set, NULL);
    return ret;
}

/**
 * @brief Print LYB magic number.
 *
 * @param[in] out Out structure.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_magic_number(struct ly_out *out)
{
    /* 'l', 'y', 'b' - 0x6c7962 */
    char magic_number[] = {'l', 'y', 'b'};

    LY_CHECK_RET(ly_write_(out, magic_number, 3));

    return LY_SUCCESS;
}

/**
 * @brief Print LYB header.
 *
 * @param[in] out Out structure.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_header(struct ly_out *out)
{
    uint8_t byte = 0;

    /* version, future flags */
    byte |= LYB_VERSION_NUM;

    LY_CHECK_RET(ly_write_(out, (char *)&byte, 1));

    return LY_SUCCESS;
}

/**
 * @brief Print prefix data.
 *
 * @param[in] out Out structure.
 * @param[in] format Value prefix format.
 * @param[in] prefix_data Format-specific data for resolving any prefixes (see ::ly_resolve_prefix).
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_prefix_data(struct ly_out *out, LY_VALUE_FORMAT format, const void *prefix_data, struct lylyb_ctx *lybctx)
{
    const struct ly_set *set;
    const struct lyxml_ns *ns;
    uint32_t i;

    switch (format) {
    case LY_VALUE_XML:
        set = prefix_data;
        if (!set) {
            /* no prefix data */
            i = 0;
            LY_CHECK_RET(lyb_write(out, (uint8_t *)&i, 1, lybctx));
            break;
        }
        if (set->count > UINT8_MAX) {
            LOGERR(lybctx->ctx, LY_EINT, "Maximum supported number of prefixes is %u.", UINT8_MAX);
            return LY_EINT;
        }

        /* write number of prefixes on 1 byte */
        LY_CHECK_RET(lyb_write_number(set->count, 1, out, lybctx));

        /* write all the prefixes */
        for (i = 0; i < set->count; ++i) {
            ns = set->objs[i];

            /* prefix */
            LY_CHECK_RET(lyb_write_string(ns->prefix, 0, 1, out, lybctx));

            /* namespace */
            LY_CHECK_RET(lyb_write_string(ns->uri, 0, 1, out, lybctx));
        }
        break;
    case LY_VALUE_JSON:
    case LY_VALUE_LYB:
        /* nothing to print */
        break;
    default:
        LOGINT_RET(lybctx->ctx);
    }

    return LY_SUCCESS;
}

/**
 * @brief Print term node.
 *
 * @param[in] term Node to print.
 * @param[in] out Out structure.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_term_value(struct lyd_node_term *term, struct ly_out *out, struct lylyb_ctx *lybctx)
{
    LY_ERR ret = LY_SUCCESS;
    ly_bool dynamic = 0;
    void *value;
    size_t value_len = 0;
    int32_t lyb_data_len;
    lyplg_type_print_clb print;

    assert(term->value.realtype && term->value.realtype->plugin && term->value.realtype->plugin->print &&
            term->schema);

    /* Get length of LYB data to print. */
    lyb_data_len = term->value.realtype->plugin->lyb_data_len;

    /* Get value and also print its length only if size is not fixed. */
    print = term->value.realtype->plugin->print;
    if (lyb_data_len < 0) {
        /* Variable-length data. */

        /* Get value and its length from plugin. */
        value = (void *)print(term->schema->module->ctx, &term->value,
                LY_VALUE_LYB, NULL, &dynamic, &value_len);
        LY_CHECK_GOTO(ret, cleanup);

        if (value_len > UINT32_MAX) {
            LOGERR(lybctx->ctx, LY_EINT, "The maximum length of the LYB data "
                    "from a term node must not exceed %lu.", UINT32_MAX);
            ret = LY_EINT;
            goto cleanup;
        }

        /* Print the length of the data as 32-bit unsigned integer. */
        ret = lyb_write_number(value_len, sizeof(uint32_t), out, lybctx);
        LY_CHECK_GOTO(ret, cleanup);
    } else {
        /* Fixed-length data. */

        /* Get value from plugin. */
        value = (void *)print(term->schema->module->ctx, &term->value,
                LY_VALUE_LYB, NULL, &dynamic, NULL);
        LY_CHECK_GOTO(ret, cleanup);

        /* Copy the length from the compiled node. */
        value_len = lyb_data_len;
    }

    /* Print value. */
    if (value_len > 0) {
        /* Print the value simply as it is. */
        ret = lyb_write(out, value, value_len, lybctx);
        LY_CHECK_GOTO(ret, cleanup);
    }

cleanup:
    if (dynamic) {
        free(value);
    }

    return ret;
}

/**
 * @brief Print YANG node metadata.
 *
 * @param[in] out Out structure.
 * @param[in] node Data node whose metadata to print.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_metadata(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx)
{
    uint8_t count = 0;
    const struct lys_module *wd_mod = NULL;
    struct lyd_meta *iter;

    /* with-defaults */
    if (node->schema->nodetype & LYD_NODE_TERM) {
        if (((node->flags & LYD_DEFAULT) && (lybctx->print_options & (LYD_PRINT_WD_ALL_TAG | LYD_PRINT_WD_IMPL_TAG))) ||
                ((lybctx->print_options & LYD_PRINT_WD_ALL_TAG) && lyd_is_default(node))) {
            /* we have implicit OR explicit default node, print attribute only if context include with-defaults schema */
            wd_mod = ly_ctx_get_module_latest(node->schema->module->ctx, "ietf-netconf-with-defaults");
        }
    }

    /* count metadata */
    if (wd_mod) {
        ++count;
    }
    for (iter = node->meta; iter; iter = iter->next) {
        if (count == UINT8_MAX) {
            LOGERR(lybctx->lybctx->ctx, LY_EINT, "Maximum supported number of data node metadata is %u.", UINT8_MAX);
            return LY_EINT;
        }
        ++count;
    }

    /* write number of metadata on 1 byte */
    LY_CHECK_RET(lyb_write(out, &count, 1, lybctx->lybctx));

    if (wd_mod) {
        /* write the "default" metadata */
        LY_CHECK_RET(lyb_write_start_siblings(out, lybctx->lybctx));
        LY_CHECK_RET(lyb_print_model(out, wd_mod, lybctx->lybctx));
        LY_CHECK_RET(lyb_write_string("default", 0, 1, out, lybctx->lybctx));
        LY_CHECK_RET(lyb_write_string("true", 0, 0, out, lybctx->lybctx));
        LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx->lybctx));
    }

    /* write all the node metadata */
    LY_LIST_FOR(node->meta, iter) {
        /* each metadata is a sibling */
        LY_CHECK_RET(lyb_write_start_siblings(out, lybctx->lybctx));

        /* model */
        LY_CHECK_RET(lyb_print_model(out, iter->annotation->module, lybctx->lybctx));

        /* annotation name with length */
        LY_CHECK_RET(lyb_write_string(iter->name, 0, 1, out, lybctx->lybctx));

        /* metadata value */
        LY_CHECK_RET(lyb_write_string(lyd_get_meta_value(iter), 0, 0, out, lybctx->lybctx));

        /* finish metadata sibling */
        LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx->lybctx));
    }

    return LY_SUCCESS;
}

/**
 * @brief Print opaque node attributes.
 *
 * @param[in] out Out structure.
 * @param[in] node Opaque node whose attributes to print.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_attributes(struct ly_out *out, const struct lyd_node_opaq *node, struct lylyb_ctx *lybctx)
{
    uint8_t count = 0;
    struct lyd_attr *iter;

    for (iter = node->attr; iter; iter = iter->next) {
        if (count == UINT8_MAX) {
            LOGERR(lybctx->ctx, LY_EINT, "Maximum supported number of data node attributes is %u.", UINT8_MAX);
            return LY_EINT;
        }
        ++count;
    }

    /* write number of attributes on 1 byte */
    LY_CHECK_RET(lyb_write(out, &count, 1, lybctx));

    /* write all the attributes */
    LY_LIST_FOR(node->attr, iter) {
        /* each attribute is a sibling */
        LY_CHECK_RET(lyb_write_start_siblings(out, lybctx));

        /* prefix */
        LY_CHECK_RET(lyb_write_string(iter->name.prefix, 0, 1, out, lybctx));

        /* namespace */
        LY_CHECK_RET(lyb_write_string(iter->name.module_name, 0, 1, out, lybctx));

        /* name */
        LY_CHECK_RET(lyb_write_string(iter->name.name, 0, 1, out, lybctx));

        /* format */
        LY_CHECK_RET(lyb_write_number(iter->format, 1, out, lybctx));

        /* value prefixes */
        LY_CHECK_RET(lyb_print_prefix_data(out, iter->format, iter->val_prefix_data, lybctx));

        /* value */
        LY_CHECK_RET(lyb_write_string(iter->value, 0, 0, out, lybctx));

        /* finish attribute sibling */
        LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx));
    }

    return LY_SUCCESS;
}

/**
 * @brief Print schema node hash.
 *
 * @param[in] out Out structure.
 * @param[in] schema Schema node whose hash to print.
 * @param[in,out] sibling_ht Cached hash table for these siblings, created if NULL.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_schema_hash(struct ly_out *out, struct lysc_node *schema, struct hash_table **sibling_ht, struct lylyb_ctx *lybctx)
{
    LY_ARRAY_COUNT_TYPE u;
    uint32_t i;
    LYB_HASH hash;
    struct lyd_lyb_sib_ht *sib_ht;
    struct lysc_node *first_sibling;

    if (!schema) {
        /* opaque node, write empty hash */
        hash = 0;
        LY_CHECK_RET(lyb_write(out, &hash, sizeof hash, lybctx));
        return LY_SUCCESS;
    }

    /* create whole sibling HT if not already created and saved */
    if (!*sibling_ht) {
        /* get first schema data sibling */
        first_sibling = (struct lysc_node *)lys_getnext(NULL, lysc_data_parent(schema), schema->module->compiled,
                (schema->flags & LYS_IS_OUTPUT) ? LYS_GETNEXT_OUTPUT : 0);
        LY_ARRAY_FOR(lybctx->sib_hts, u) {
            if (lybctx->sib_hts[u].first_sibling == first_sibling) {
                /* we have already created a hash table for these siblings */
                *sibling_ht = lybctx->sib_hts[u].ht;
                break;
            }
        }

        if (!*sibling_ht) {
            /* we must create sibling hash table */
            LY_CHECK_RET(lyb_hash_siblings(first_sibling, sibling_ht));

            /* and save it */
            LY_ARRAY_NEW_RET(lybctx->ctx, lybctx->sib_hts, sib_ht, LY_EMEM);

            sib_ht->first_sibling = first_sibling;
            sib_ht->ht = *sibling_ht;
        }
    }

    /* get our hash */
    LY_CHECK_RET(lyb_hash_find(*sibling_ht, schema, &hash));

    /* write the hash */
    LY_CHECK_RET(lyb_write(out, &hash, sizeof hash, lybctx));

    if (hash & LYB_HASH_COLLISION_ID) {
        /* no collision for this hash, we are done */
        return LY_SUCCESS;
    }

    /* written hash was a collision, write also all the preceding hashes */
    for (i = 0; !(hash & (LYB_HASH_COLLISION_ID >> i)); ++i) {}

    for ( ; i; --i) {
        hash = lyb_get_hash(schema, i - 1);
        if (!hash) {
            return LY_EINT;
        }
        assert(hash & (LYB_HASH_COLLISION_ID >> (i - 1)));

        LY_CHECK_RET(lyb_write(out, &hash, sizeof hash, lybctx));
    }

    return LY_SUCCESS;
}

/**
 * @brief Print header for non-opaq node.
 *
 * @param[in] out Out structure.
 * @param[in] node Current data node to print.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node_header(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx)
{
    /* write any metadata */
    LY_CHECK_RET(lyb_print_metadata(out, node, lybctx));

    /* write node flags */
    LY_CHECK_RET(lyb_write_number(node->flags, sizeof node->flags, out, lybctx->lybctx));

    return LY_SUCCESS;
}

/**
 * @brief Print inner node.
 *
 * @param[in] out Out structure.
 * @param[in] node Current data node to print.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node_inner(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx)
{
    /* write necessary basic data */
    LY_CHECK_RET(lyb_print_node_header(out, node, lybctx));

    /* recursively write all the descendants */
    LY_CHECK_RET(lyb_print_siblings(out, lyd_child(node), lybctx));

    return LY_SUCCESS;
}

/**
 * @brief Print opaque node and its descendants.
 *
 * @param[in] out Out structure.
 * @param[in] opaq Node to print.
 * @param[in] lyd_lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node_opaq(struct ly_out *out, const struct lyd_node_opaq *opaq, struct lyd_lyb_ctx *lyd_lybctx)
{
    struct lylyb_ctx *lybctx = lyd_lybctx->lybctx;

    /* write attributes */
    LY_CHECK_RET(lyb_print_attributes(out, opaq, lybctx));

    /* write node flags */
    LY_CHECK_RET(lyb_write_number(opaq->flags, sizeof opaq->flags, out, lybctx));

    /* prefix */
    LY_CHECK_RET(lyb_write_string(opaq->name.prefix, 0, 1, out, lybctx));

    /* module reference */
    LY_CHECK_RET(lyb_write_string(opaq->name.module_name, 0, 1, out, lybctx));

    /* name */
    LY_CHECK_RET(lyb_write_string(opaq->name.name, 0, 1, out, lybctx));

    /* value */
    LY_CHECK_RET(lyb_write_string(opaq->value, 0, 1, out, lybctx));

    /* format */
    LY_CHECK_RET(lyb_write_number(opaq->format, 1, out, lybctx));

    /* value prefixes */
    LY_CHECK_RET(lyb_print_prefix_data(out, opaq->format, opaq->val_prefix_data, lybctx));

    /* recursively write all the descendants */
    LY_CHECK_RET(lyb_print_siblings(out, opaq->child, lyd_lybctx));

    return LY_SUCCESS;
}

/**
 * @brief Print anydata or anyxml node.
 *
 * @param[in] anydata Node to print.
 * @param[in] out Out structure.
 * @param[in] lyd_lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node_any(struct ly_out *out, struct lyd_node_any *anydata, struct lyd_lyb_ctx *lyd_lybctx)
{
    LY_ERR ret = LY_SUCCESS;
    LYD_ANYDATA_VALUETYPE value_type;
    int len;
    char *buf = NULL;
    const char *str;
    struct ly_out *out2 = NULL;
    struct lylyb_ctx *lybctx = lyd_lybctx->lybctx;

    if (anydata->value_type == LYD_ANYDATA_DATATREE) {
        /* will be printed as a nested LYB data tree */
        value_type = LYD_ANYDATA_LYB;
    } else {
        value_type = anydata->value_type;
    }

    /* write necessary basic data */
    LY_CHECK_RET(lyb_print_node_header(out, (struct lyd_node *)anydata, lyd_lybctx));

    /* first byte is type */
    LY_CHECK_GOTO(ret = lyb_write_number(value_type, sizeof value_type, out, lybctx), cleanup);

    if (anydata->value_type == LYD_ANYDATA_DATATREE) {
        /* print LYB data tree to memory */
        LY_CHECK_GOTO(ret = ly_out_new_memory(&buf, 0, &out2), cleanup);
        LY_CHECK_GOTO(ret = lyb_print_data(out2, anydata->value.tree, LYD_PRINT_WITHSIBLINGS), cleanup);

        len = lyd_lyb_data_length(buf);
        assert(len != -1);
        str = buf;
    } else if (anydata->value_type == LYD_ANYDATA_LYB) {
        len = lyd_lyb_data_length(anydata->value.mem);
        assert(len != -1);
        str = anydata->value.mem;
    } else {
        len = strlen(anydata->value.str);
        str = anydata->value.str;
    }

    /* followed by the content */
    LY_CHECK_GOTO(ret = lyb_write_string(str, (size_t)len, 1, out, lybctx), cleanup);

cleanup:
    ly_out_free(out2, NULL, 1);
    return ret;
}

/**
 * @brief Print leaf node.
 *
 * @param[in] out Out structure.
 * @param[in] node Current data node to print.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node_leaf(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx)
{
    /* write necessary basic data */
    LY_CHECK_RET(lyb_print_node_header(out, node, lybctx));

    /* write term value */
    LY_CHECK_RET(lyb_print_term_value((struct lyd_node_term *)node, out, lybctx->lybctx));

    return LY_SUCCESS;
}

/**
 * @brief Print all leaflist nodes which belong to same schema.
 *
 * @param[in] out Out structure.
 * @param[in] node Current data node to print.
 * @param[in] lybctx LYB context.
 * @param[out] printed_node Last node that was printed by this function.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node_leaflist(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx,
        const struct lyd_node **printed_node)
{
    const struct lysc_node *schema;

    /* register a new sibling */
    LY_CHECK_RET(lyb_write_start_siblings(out, lybctx->lybctx));

    schema = node->schema;

    /* write all the siblings */
    LY_LIST_FOR(node, node) {
        if (schema != node->schema) {
            /* all leaflist nodes was printed */
            break;
        }

        /* write leaf data */
        LY_CHECK_RET(lyb_print_node_leaf(out, node, lybctx));
        *printed_node = node;
    }

    /* finish this sibling */
    LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx->lybctx));

    return LY_SUCCESS;
}

/**
 * @brief Print all list nodes which belong to same schema.
 *
 * @param[in] out Out structure.
 * @param[in] node Current data node to print.
 * @param[in] lybctx LYB context.
 * @param[out] printed_node Last node that was printed by this function.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node_list(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx,
        const struct lyd_node **printed_node)
{
    const struct lysc_node *schema;

    /* register a new sibling */
    LY_CHECK_RET(lyb_write_start_siblings(out, lybctx->lybctx));

    schema = node->schema;

    LY_LIST_FOR(node, node) {
        if (schema != node->schema) {
            /* all list nodes was printed */
            break;
        }

        /* write necessary basic data */
        LY_CHECK_RET(lyb_print_node_header(out, node, lybctx));

        /* recursively write all the descendants */
        LY_CHECK_RET(lyb_print_siblings(out, lyd_child(node), lybctx));

        *printed_node = node;
    }

    /* finish this sibling */
    LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx->lybctx));

    return LY_SUCCESS;
}

/**
 * @brief Print node.
 *
 * @param[in] out Out structure.
 * @param[in,out] printed_node Current data node to print. Sets to the last printed node.
 * @param[in,out] sibling_ht Cached hash table for these siblings, created if NULL.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_node(struct ly_out *out, const struct lyd_node **printed_node, struct hash_table **sibling_ht,
        struct lyd_lyb_ctx *lybctx)
{
    const struct lyd_node *node = *printed_node;

    /* write model info first, for all opaque and top-level nodes */
    if (!node->schema && (!node->parent || !node->parent->schema)) {
        LY_CHECK_RET(lyb_print_model(out, NULL, lybctx->lybctx));
    } else if (node->schema && !lysc_data_parent(node->schema)) {
        LY_CHECK_RET(lyb_print_model(out, node->schema->module, lybctx->lybctx));
    }

    /* write schema hash */
    LY_CHECK_RET(lyb_print_schema_hash(out, (struct lysc_node *)node->schema, sibling_ht, lybctx->lybctx));

    if (!node->schema) {
        LY_CHECK_RET(lyb_print_node_opaq(out, (struct lyd_node_opaq *)node, lybctx));
    } else if (node->schema->nodetype & LYS_LEAFLIST) {
        LY_CHECK_RET(lyb_print_node_leaflist(out, node, lybctx, &node));
    } else if (node->schema->nodetype == LYS_LIST) {
        LY_CHECK_RET(lyb_print_node_list(out, node, lybctx, &node));
    } else if (node->schema->nodetype & LYD_NODE_ANY) {
        LY_CHECK_RET(lyb_print_node_any(out, (struct lyd_node_any *)node, lybctx));
    } else if (node->schema->nodetype & LYD_NODE_INNER) {
        LY_CHECK_RET(lyb_print_node_inner(out, node, lybctx));
    } else {
        LY_CHECK_RET(lyb_print_node_leaf(out, node, lybctx));
    }

    *printed_node = node;

    return LY_SUCCESS;
}

/**
 * @brief Print siblings.
 *
 * @verbatim

 sb          = siblings_start
 se          = siblings_end
 siblings    = 8bit_zero | (sb instance+ se)
 instance    = model hash node
 model       = 16bit_zero | (model_name_length model_name revision)
 node        = opaq | leaflist | list | any | inner | leaf
 opaq        = opaq_data siblings
 leaflist    = sb leaf+ se
 list        = sb (node_header siblings)+ se
 any         = node_header anydata_data
 inner       = node_header siblings
 leaf        = node_header term_value
 node_header = metadata node_flags

 @endverbatim
 *
 * @param[in] out Out structure.
 * @param[in] node Current data node to print.
 * @param[in] lybctx LYB context.
 * @return LY_ERR value.
 */
static LY_ERR
lyb_print_siblings(struct ly_out *out, const struct lyd_node *node, struct lyd_lyb_ctx *lybctx)
{
    struct hash_table *sibling_ht = NULL;
    const struct lys_module *prev_mod = NULL;
    ly_bool top_level;
    uint8_t zero = 0;

    if (!node) {
        lyb_write(out, &zero, 1, lybctx->lybctx);
        return LY_SUCCESS;
    }

    top_level = !LY_ARRAY_COUNT(lybctx->lybctx->siblings);

    LY_CHECK_RET(lyb_write_start_siblings(out, lybctx->lybctx));

    if (top_level) {
        /* write all the siblings */
        LY_LIST_FOR(node, node) {
            /* do not reuse sibling hash tables from different modules */
            if (!node->schema || (node->schema->module != prev_mod)) {
                sibling_ht = NULL;
                prev_mod = node->schema ? node->schema->module : NULL;
            }

            LY_CHECK_RET(lyb_print_node(out, &node, &sibling_ht, lybctx));

            if (!(lybctx->print_options & LYD_PRINT_WITHSIBLINGS)) {
                break;
            }
        }
    } else {
        LY_LIST_FOR(node, node) {
            LY_CHECK_RET(lyb_print_node(out, &node, &sibling_ht, lybctx));
        }
    }

    LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx->lybctx));

    return LY_SUCCESS;
}

LY_ERR
lyb_print_data(struct ly_out *out, const struct lyd_node *root, uint32_t options)
{
    LY_ERR ret = LY_SUCCESS;
    uint8_t zero = 0;
    struct lyd_lyb_ctx *lybctx;
    const struct ly_ctx *ctx = root ? LYD_CTX(root) : NULL;

    lybctx = calloc(1, sizeof *lybctx);
    LY_CHECK_ERR_RET(!lybctx, LOGMEM(ctx), LY_EMEM);
    lybctx->lybctx = calloc(1, sizeof *lybctx->lybctx);
    LY_CHECK_ERR_RET(!lybctx, LOGMEM(ctx), LY_EMEM);

    lybctx->print_options = options;
    if (root) {
        lybctx->lybctx->ctx = ctx;

        if (root->schema && lysc_data_parent(root->schema)) {
            LOGERR(lybctx->lybctx->ctx, LY_EINVAL, "LYB printer supports only printing top-level nodes.");
            ret = LY_EINVAL;
            goto cleanup;
        }
    }

    /* LYB magic number */
    LY_CHECK_GOTO(ret = lyb_print_magic_number(out), cleanup);

    /* LYB header */
    LY_CHECK_GOTO(ret = lyb_print_header(out), cleanup);

    /* all used models */
    LY_CHECK_GOTO(ret = lyb_print_data_models(out, root, lybctx->lybctx), cleanup);

    ret = lyb_print_siblings(out, root, lybctx);
    LY_CHECK_GOTO(ret, cleanup);

    /* ending zero byte */
    LY_CHECK_GOTO(ret = lyb_write(out, &zero, sizeof zero, lybctx->lybctx), cleanup);

cleanup:
    lyd_lyb_ctx_free((struct lyd_ctx *)lybctx);
    return ret;
}
