/**
 * @file plugins_exts_yangdata.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief libyang extension plugin - yang-data (RFC 8040)
 *
 * 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 <stdlib.h>

#include "common.h"
#include "plugins_exts.h"
#include "schema_compile.h"
#include "tree_schema.h"

/**
 * @brief Storage for ID used to check plugin API version compatibility.
 * Ignored here in the internal plugin.
LYEXT_VERSION_CHECK
 */

/**
 * @brief Free yang-data extension instances' data.
 *
 * Implementation of ::lyext_clb_free callback set as lyext_plugin::free.
 */
void
yangdata_free(struct ly_ctx *ctx, struct lysc_ext_instance *ext)
{
    lysc_extension_instance_substatements_free(ctx, ext->substmts);
}

/**
 * @brief Compile yang-data extension instances.
 *
 * Implementation of lyext_clb_compile callback set as lyext_plugin::compile.
 */
LY_ERR
yangdata_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
{
    LY_ERR ret;
    LY_ARRAY_COUNT_TYPE u;
    struct lysc_module *mod_c;
    const struct lysc_node *child;
    ly_bool valid = 1;
    uint32_t prev_options = cctx->options;

    /* yang-data can appear only at the top level of a YANG module or submodule */
    if (c_ext->parent_type != LYEXT_PAR_MODULE) {
        lyext_log(c_ext, LY_LLWRN, 0, cctx->path,
                "Extension %s is ignored since it appears as a non top-level statement in \"%s\" statement.",
                p_ext->name, lyext_parent2str(c_ext->parent_type));
        return LY_ENOT;
    }
    /* check mandatory argument */
    if (!c_ext->argument) {
        lyext_log(c_ext, LY_LLERR, LY_EVALID, cctx->path,
                "Extension %s is instantiated without mandatory argument representing YANG data template name.",
                p_ext->name);
        return LY_EVALID;
    }

    mod_c = (struct lysc_module *)c_ext->parent;

    /* check for duplication */
    LY_ARRAY_FOR(mod_c->exts, u) {
        if ((&mod_c->exts[u] != c_ext) && (mod_c->exts[u].def == c_ext->def) && !strcmp(mod_c->exts[u].argument, c_ext->argument)) {
            /* duplication of the same yang-data extension in a single module */
            lyext_log(c_ext, LY_LLERR, LY_EVALID, cctx->path, "Extension %s is instantiated multiple times.", p_ext->name);
            return LY_EVALID;
        }
    }

    /* compile annotation substatements
     * To let the compilation accept different statements possibly leading to the container top-level node, there are 3
     * allowed substatements pointing to a single storage. But when compiled, the substaments list is compressed just to
     * a single item providing the schema tree. */
    LY_ARRAY_CREATE_RET(cctx->ctx, c_ext->substmts, 3, LY_EMEM);
    LY_ARRAY_INCREMENT(c_ext->substmts);
    c_ext->substmts[0].stmt = LY_STMT_CONTAINER;
    c_ext->substmts[0].cardinality = LY_STMT_CARD_OPT;
    c_ext->substmts[0].storage = &c_ext->data;

    LY_ARRAY_INCREMENT(c_ext->substmts);
    c_ext->substmts[1].stmt = LY_STMT_CHOICE;
    c_ext->substmts[1].cardinality = LY_STMT_CARD_OPT;
    c_ext->substmts[1].storage = &c_ext->data;

    LY_ARRAY_INCREMENT(c_ext->substmts);
    c_ext->substmts[2].stmt = LY_STMT_USES;
    c_ext->substmts[2].cardinality = LY_STMT_CARD_OPT;
    c_ext->substmts[2].storage = &c_ext->data;

    cctx->options |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
    ret = lys_compile_extension_instance(cctx, p_ext, c_ext);
    cctx->options = prev_options;
    LY_ARRAY_DECREMENT(c_ext->substmts);
    LY_ARRAY_DECREMENT(c_ext->substmts);
    LY_CHECK_RET(ret);

    /* check that we have really just a single container data definition in the top */
    child = *(struct lysc_node **)c_ext->substmts[0].storage;
    if (!child) {
        valid = 0;
        lyext_log(c_ext, LY_LLERR, LY_EVALID, cctx->path,
                "Extension %s is instantiated without any top level data node, but exactly one container data node is expected.",
                p_ext->name);
    } else if (child->next) {
        valid = 0;
        lyext_log(c_ext, LY_LLERR, LY_EVALID, cctx->path,
                "Extension %s is instantiated with multiple top level data nodes, but only a single container data node is allowed.",
                p_ext->name);
    } else if (child->nodetype == LYS_CHOICE) {
        /* all the choice's case are expected to result to a single container node */
        const struct lysc_node *snode = NULL;

        while ((snode = lys_getnext(snode, child, mod_c, 0))) {
            if (snode->next) {
                valid = 0;
                lyext_log(c_ext, LY_LLERR, LY_EVALID, cctx->path,
                        "Extension %s is instantiated with multiple top level data nodes (inside a single choice's case), "
                        "but only a single container data node is allowed.", p_ext->name);
                break;
            } else if (snode->nodetype != LYS_CONTAINER) {
                valid = 0;
                lyext_log(c_ext, LY_LLERR, LY_EVALID, cctx->path,
                        "Extension %s is instantiated with %s top level data node (inside a choice), "
                        "but only a single container data node is allowed.", p_ext->name, lys_nodetype2str(snode->nodetype));
                break;
            }
        }
    } else if (child->nodetype != LYS_CONTAINER) {
        /* via uses */
        valid = 0;
        lyext_log(c_ext, LY_LLERR, LY_EVALID, cctx->path,
                "Extension %s is instantiated with %s top level data node, but only a single container data node is allowed.",
                p_ext->name, lys_nodetype2str(child->nodetype));
    }

    if (!valid) {
        yangdata_free(cctx->ctx, c_ext);
        c_ext->data = c_ext->substmts = NULL;
        return LY_EVALID;
    }

    return LY_SUCCESS;
}

/**
 * @brief INFO printer
 *
 * Implementation of ::lyext_clb_schema_printer set as ::lyext_plugin::sprinter
 */
LY_ERR
yangdata_schema_printer(struct lys_ypr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag)
{
    lysc_print_extension_instance(ctx, ext, flag);
    return LY_SUCCESS;
}

/**
 * @brief Plugin for the yang-data extension
 */
struct lyext_plugin yangdata_plugin = {
    .id = "libyang 2 - yang-data, version 1",
    .compile = &yangdata_compile,
    .validate = NULL,
    .sprinter = &yangdata_schema_printer,
    .free = yangdata_free
};
