/**
 * @file lyb.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @brief LYB format common functionality.
 *
 * Copyright (c) 2021 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 <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "compat.h"
#include "ly_common.h"
#include "tree_schema.h"

/**
 * @brief Generate single hash for a schema node to be used for LYB data.
 *
 * @param[in] node Node to hash.
 * @param[in] collision_id Collision ID of the hash to generate.
 * @return Generated hash.
 */
static LYB_HASH
lyb_generate_hash(const struct lysc_node *node, uint8_t collision_id)
{
    const struct lys_module *mod = node->module;
    uint32_t full_hash;
    LYB_HASH hash;

    /* generate full hash */
    full_hash = lyht_hash_multi(0, mod->name, strlen(mod->name));
    full_hash = lyht_hash_multi(full_hash, node->name, strlen(node->name));
    if (collision_id) {
        size_t ext_len;

        if (collision_id > strlen(mod->name)) {
            /* fine, we will not hash more bytes, just use more bits from the hash than previously */
            ext_len = strlen(mod->name);
        } else {
            /* use one more byte from the module name than before */
            ext_len = collision_id;
        }
        full_hash = lyht_hash_multi(full_hash, mod->name, ext_len);
    }
    full_hash = lyht_hash_multi(full_hash, NULL, 0);

    /* use the shortened hash */
    hash = full_hash & (LYB_HASH_MASK >> collision_id);
    /* add collision identificator */
    hash |= LYB_HASH_COLLISION_ID >> collision_id;

    return hash;
}

LYB_HASH
lyb_get_hash(const struct lysc_node *node, uint8_t collision_id)
{
    /* hashes must be cached */
    assert(node->hash[0]);

    if (collision_id < LYS_NODE_HASH_COUNT) {
        /* read from cache */
        return node->hash[collision_id];
    }

    /* generate */
    return lyb_generate_hash(node, collision_id);
}

/**
 * @brief Module DFS callback filling all cached hashes of a schema node.
 */
static LY_ERR
lyb_cache_node_hash_cb(struct lysc_node *node, void *UNUSED(data), ly_bool *UNUSED(dfs_continue))
{
    if (node->hash[0]) {
        /* already cached, stop the DFS */
        return LY_EEXIST;
    }

    for (uint8_t i = 0; i < LYS_NODE_HASH_COUNT; ++i) {
        /* store the hash in the cache */
        node->hash[i] = lyb_generate_hash(node, i);
    }

    return LY_SUCCESS;
}

void
lyb_cache_module_hash(const struct lys_module *mod)
{
    /* LOCK */
    pthread_mutex_lock(&mod->ctx->lyb_hash_lock);

    /* store all cached hashes for all the nodes */
    lysc_module_dfs_full(mod, lyb_cache_node_hash_cb, NULL);

    /* UNLOCK */
    pthread_mutex_unlock(&mod->ctx->lyb_hash_lock);
}

ly_bool
lyb_has_schema_model(const struct lysc_node *node, const struct lys_module **models)
{
    LY_ARRAY_COUNT_TYPE u;

    LY_ARRAY_FOR(models, u) {
        if (node->module == models[u]) {
            return 1;
        }
    }

    return 0;
}
