/*
 * @file test_nacm.c
 * @author: Radek Krejci <rkrejci@cesnet.cz>
 * @brief unit tests for NACM extensions support
 *
 * Copyright (c) 2019 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 "tests/config.h"

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

#include <stdio.h>
#include <string.h>

#include "../../src/libyang.h"

#define BUFSIZE 1024
char logbuf[BUFSIZE] = {0};
int store = -1; /* negative for infinite logging, positive for limited logging */

struct state_s {
    void *func;
    struct ly_ctx *ctx;
};

/* set to 0 to printing error messages to stderr instead of checking them in code */
#define ENABLE_LOGGER_CHECKING 1

#if ENABLE_LOGGER_CHECKING
static void
logger(LY_LOG_LEVEL level, const char *msg, const char *path)
{
    (void) level; /* unused */
    if (store) {
        if (path && path[0]) {
            snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
        } else {
            strncpy(logbuf, msg, BUFSIZE - 1);
        }
        if (store > 0) {
            --store;
        }
    }
}
#endif

static int
setup(void **state)
{
    struct state_s *s;

    s = calloc(1, sizeof *s);
    assert_non_null(s);

#if ENABLE_LOGGER_CHECKING
    ly_set_log_clb(logger, 1);
#endif

    assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &s->ctx));
    assert_non_null(ly_ctx_load_module(s->ctx, "ietf-netconf-acm", "2018-02-14"));

    *state = s;

    return 0;
}

static int
teardown(void **state)
{
    struct state_s *s = (struct state_s*)(*state);

#if ENABLE_LOGGER_CHECKING
    if (s->func) {
        fprintf(stderr, "%s\n", logbuf);
    }
#endif

    ly_ctx_destroy(s->ctx, NULL);
    free(s);

    return 0;
}

void
logbuf_clean(void)
{
    logbuf[0] = '\0';
}

#if ENABLE_LOGGER_CHECKING
#   define logbuf_assert(str) assert_string_equal(logbuf, str)
#else
#   define logbuf_assert(str)
#endif

static void
test_deny_all(void **state)
{
    struct state_s *s = (struct state_s*)(*state);
    s->func = test_deny_all;

    struct lys_module *mod;
    struct lysc_node_container *cont;
    struct lysc_node_leaf *leaf;
    struct lysc_ext_instance *e;

    const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:nacm:a; prefix en;"
            "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
            "container a { nacm:default-deny-all; leaf aa {type string;}}"
            "leaf b {type string;}}";

    /* valid data */
    assert_non_null(mod = lys_parse_mem(s->ctx, data, LYS_IN_YANG));
    assert_non_null(cont = (struct lysc_node_container*)mod->compiled->data);
    assert_non_null(leaf = (struct lysc_node_leaf*)cont->child);
    assert_non_null(e = &cont->exts[0]);
    assert_int_equal(LY_ARRAY_SIZE(cont->exts), 1);
    assert_int_equal(LY_ARRAY_SIZE(leaf->exts), 1); /* NACM extensions inherit */
    assert_ptr_equal(e->def, leaf->exts[0].def);
    assert_int_equal(1, *((uint8_t*)e->data)); /* plugin's value for default-deny-all */
    assert_null(cont->next->exts);

    /* invalid */
    data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
            "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
            "nacm:default-deny-all;}";
    assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
    logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
            "Extension nacm:default-deny-all is allowed only in a data nodes, but it is placed in \"module\" statement.) /");

    data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
            "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
            "leaf l { type string; nacm:default-deny-all; nacm:default-deny-write;}}";
    assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
    logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
            "Extension nacm:default-deny-write is mixed with nacm:default-deny-all.) /aa:l");

    s->func = NULL;
}

static void
test_deny_write(void **state)
{
    struct state_s *s = (struct state_s*)(*state);
    s->func = test_deny_write;

    struct lys_module *mod;
    struct lysc_node_container *cont;
    struct lysc_node_leaf *leaf;
    struct lysc_ext_instance *e;

    const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:nacm:a; prefix en;"
            "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
            "container a { nacm:default-deny-write; leaf aa {type string;}}"
            "leaf b {type string;}}";

    /* valid data */
    assert_non_null(mod = lys_parse_mem(s->ctx, data, LYS_IN_YANG));
    assert_non_null(cont = (struct lysc_node_container*)mod->compiled->data);
    assert_non_null(leaf = (struct lysc_node_leaf*)cont->child);
    assert_non_null(e = &cont->exts[0]);
    assert_int_equal(LY_ARRAY_SIZE(cont->exts), 1);
    assert_int_equal(LY_ARRAY_SIZE(leaf->exts), 1); /* NACM extensions inherit */
    assert_ptr_equal(e->def, leaf->exts[0].def);
    assert_int_equal(2, *((uint8_t*)e->data)); /* plugin's value for default-deny-write */
    assert_null(cont->next->exts);

    /* invalid */
    data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
            "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
            "notification notif {nacm:default-deny-write;}}";
    assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
    logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
            "Extension nacm:default-deny-write is not allowed in Notification statement.) /aa:notif");

    data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
            "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
            "leaf l { type string; nacm:default-deny-write; nacm:default-deny-write;}}";
    assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
    logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
            "Extension nacm:default-deny-write is instantiated multiple times.) /aa:l");

    s->func = NULL;
}

int main(void)
{
    const struct CMUnitTest tests[] = {
        cmocka_unit_test_setup_teardown(test_deny_all, setup, teardown),
        cmocka_unit_test_setup_teardown(test_deny_write, setup, teardown),
    };

    return cmocka_run_group_tests(tests, NULL, NULL);
}
