/**
 * @file schema_features.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief Schema feature handling
 *
 * Copyright (c) 2015 - 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
 */

#define _GNU_SOURCE

#include "schema_features.h"

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

#include "common.h"
#include "log.h"
#include "set.h"
#include "tree.h"
#include "tree_edit.h"
#include "tree_schema.h"
#include "tree_schema_internal.h"

#define IFF_RECORDS_IN_BYTE 4
#define IFF_RECORD_BITS 2
#define IFF_RECORD_MASK 0x3

uint8_t
lysc_iff_getop(uint8_t *list, size_t pos)
{
    uint8_t *item;
    uint8_t mask = IFF_RECORD_MASK, result;

    item = &list[pos / IFF_RECORDS_IN_BYTE];
    result = (*item) & (mask << IFF_RECORD_BITS * (pos % IFF_RECORDS_IN_BYTE));
    return result >> IFF_RECORD_BITS * (pos % IFF_RECORDS_IN_BYTE);
}

static LY_ERR
lysc_iffeature_value_(const struct lysc_iffeature *iff, size_t *index_e, size_t *index_f)
{
    uint8_t op;
    LY_ERR a, b;

    op = lysc_iff_getop(iff->expr, *index_e);
    (*index_e)++;

    switch (op) {
    case LYS_IFF_F:
        /* resolve feature */
        return (iff->features[(*index_f)++]->flags & LYS_FENABLED) ? LY_SUCCESS : LY_ENOT;
    case LYS_IFF_NOT:
        /* invert result */
        return lysc_iffeature_value_(iff, index_e, index_f) == LY_SUCCESS ? LY_ENOT : LY_SUCCESS;
    case LYS_IFF_AND:
    case LYS_IFF_OR:
        a = lysc_iffeature_value_(iff, index_e, index_f);
        b = lysc_iffeature_value_(iff, index_e, index_f);
        if (op == LYS_IFF_AND) {
            if ((a == LY_SUCCESS) && (b == LY_SUCCESS)) {
                return LY_SUCCESS;
            } else {
                return LY_ENOT;
            }
        } else { /* LYS_IFF_OR */
            if ((a == LY_SUCCESS) || (b == LY_SUCCESS)) {
                return LY_SUCCESS;
            } else {
                return LY_ENOT;
            }
        }
    }

    return LY_ENOT;
}

API LY_ERR
lysc_iffeature_value(const struct lysc_iffeature *iff)
{
    size_t index_e = 0, index_f = 0;

    LY_CHECK_ARG_RET(NULL, iff, LY_EINVAL);

    if (iff->expr) {
        return lysc_iffeature_value_(iff, &index_e, &index_f);
    }
    return LY_ENOT;
}

API struct lysp_feature *
lysp_feature_next(const struct lysp_feature *last, const struct lysp_module *pmod, uint32_t *idx)
{
    struct lysp_feature *features;

    if (!*idx) {
        /* module features */
        features = pmod->features;
    } else if ((*idx - 1) < LY_ARRAY_COUNT(pmod->includes)) {
        /* submodule features */
        features = pmod->includes[*idx - 1].submodule->features;
    } else {
        /* no more features */
        return NULL;
    }

    /* get the next feature */
    if (features && (!last || (&features[LY_ARRAY_COUNT(features) - 1] != last))) {
        return !last ? &features[0] : (struct lysp_feature *)last + 1;
    }

    /* no more features in current (sub)module */
    ++(*idx);
    return lysp_feature_next(NULL, pmod, idx);
}

/**
 * @brief Find a feature of the given name and referenced in the given module.
 *
 * @param[in] pmod Module where the feature was referenced (used to resolve prefix of the feature).
 * @param[in] name Name of the feature including possible prefix.
 * @param[in] len Length of the string representing the feature identifier in the name variable (mandatory!).
 * @param[in] prefixed Whether the feature name can be prefixed.
 * @return Pointer to the feature structure if found, NULL otherwise.
 */
static struct lysp_feature *
lysp_feature_find(const struct lysp_module *pmod, const char *name, size_t len, ly_bool prefixed)
{
    const struct lys_module *mod;
    const char *ptr;
    struct lysp_feature *f = NULL;
    uint32_t idx = 0;

    assert(pmod);

    if (prefixed && (ptr = ly_strnchr(name, ':', len))) {
        /* we have a prefixed feature */
        mod = ly_resolve_prefix(pmod->mod->ctx, name, ptr - name, LY_PREF_SCHEMA, (void *)pmod);
        LY_CHECK_RET(!mod, NULL);

        pmod = mod->parsed;
        len = len - (ptr - name) - 1;
        name = ptr + 1;
    }

    /* feature without prefix, look in main module and all submodules */
    if (pmod->is_submod) {
        pmod = pmod->mod->parsed;
    }

    /* we have the correct module, get the feature */
    while ((f = lysp_feature_next(f, pmod, &idx))) {
        if (!ly_strncmp(f->name, name, len)) {
            return f;
        }
    }

    return NULL;
}

API LY_ERR
lys_feature_value(const struct lys_module *module, const char *feature)
{
    const struct lysp_feature *f;

    LY_CHECK_ARG_RET(NULL, module, module->parsed, feature, LY_EINVAL);

    /* search for the specified feature */
    f = lysp_feature_find(module->parsed, feature, strlen(feature), 0);
    LY_CHECK_RET(!f, LY_ENOTFOUND);

    /* feature disabled */
    if (!(f->flags & LYS_FENABLED)) {
        return LY_ENOT;
    }

    /* feature enabled */
    return LY_SUCCESS;
}

/**
 * @brief Stack for processing if-feature expressions.
 */
struct iff_stack {
    size_t size;    /**< number of items in the stack */
    size_t index;   /**< first empty item */
    uint8_t *stack; /**< stack - array of @ref ifftokens to create the if-feature expression in prefix format */
};
#define IFF_STACK_SIZE_STEP 4

/**
 * @brief Add @ref ifftokens into the stack.
 * @param[in] stack The if-feature stack to use.
 * @param[in] value One of the @ref ifftokens to store in the stack.
 * @return LY_EMEM in case of memory allocation error
 * @return LY_ESUCCESS if the value successfully stored.
 */
static LY_ERR
iff_stack_push(struct iff_stack *stack, uint8_t value)
{
    if (stack->index == stack->size) {
        stack->size += IFF_STACK_SIZE_STEP;
        stack->stack = ly_realloc(stack->stack, stack->size * sizeof *stack->stack);
        LY_CHECK_ERR_RET(!stack->stack, LOGMEM(NULL); stack->size = 0, LY_EMEM);
    }
    stack->stack[stack->index++] = value;
    return LY_SUCCESS;
}

/**
 * @brief Get (and remove) the last item form the stack.
 * @param[in] stack The if-feature stack to use.
 * @return The value from the top of the stack.
 */
static uint8_t
iff_stack_pop(struct iff_stack *stack)
{
    assert(stack && stack->index);

    stack->index--;
    return stack->stack[stack->index];
}

/**
 * @brief Clean up the stack.
 * @param[in] stack The if-feature stack to use.
 */
static void
iff_stack_clean(struct iff_stack *stack)
{
    stack->size = 0;
    free(stack->stack);
}

/**
 * @brief Store the @ref ifftokens (@p op) on the given position in the 2bits array
 * (libyang format of the if-feature expression).
 * @param[in,out] list The 2bits array to modify.
 * @param[in] op The operand (@ref ifftokens) to store.
 * @param[in] pos Position (0-based) where to store the given @p op.
 */
static void
iff_setop(uint8_t *list, uint8_t op, size_t pos)
{
    uint8_t *item;
    uint8_t mask = IFF_RECORD_MASK;

    assert(op <= IFF_RECORD_MASK); /* max 2 bits */

    item = &list[pos / IFF_RECORDS_IN_BYTE];
    mask = mask << IFF_RECORD_BITS * (pos % IFF_RECORDS_IN_BYTE);
    *item = (*item) & ~mask;
    *item = (*item) | (op << IFF_RECORD_BITS * (pos % IFF_RECORDS_IN_BYTE));
}

#define LYS_IFF_LP 0x04 /**< Additional, temporary, value of @ref ifftokens: ( */
#define LYS_IFF_RP 0x08 /**< Additional, temporary, value of @ref ifftokens: ) */

static LY_ERR
lys_compile_iffeature(const struct ly_ctx *ctx, struct lysp_qname *qname, struct lysc_iffeature *iff)
{
    LY_ERR rc = LY_SUCCESS;
    const char *c = qname->str;
    int64_t i, j;
    int8_t op_len, last_not = 0, checkversion = 0;
    LY_ARRAY_COUNT_TYPE f_size = 0, expr_size = 0, f_exp = 1;
    uint8_t op;
    struct iff_stack stack = {0, 0, NULL};
    struct lysp_feature *f;

    assert(c);

    /* pre-parse the expression to get sizes for arrays, also do some syntax checks of the expression */
    for (i = j = 0; c[i]; i++) {
        if (c[i] == '(') {
            j++;
            checkversion = 1;
            continue;
        } else if (c[i] == ')') {
            j--;
            continue;
        } else if (isspace(c[i])) {
            checkversion = 1;
            continue;
        }

        if (!strncmp(&c[i], "not", op_len = ly_strlen_const("not")) ||
                !strncmp(&c[i], "and", op_len = ly_strlen_const("and")) ||
                !strncmp(&c[i], "or", op_len = ly_strlen_const("or"))) {
            uint64_t spaces;
            for (spaces = 0; c[i + op_len + spaces] && isspace(c[i + op_len + spaces]); spaces++) {}
            if (c[i + op_len + spaces] == '\0') {
                LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - unexpected end of expression.", qname->str);
                return LY_EVALID;
            } else if (!isspace(c[i + op_len])) {
                /* feature name starting with the not/and/or */
                last_not = 0;
                f_size++;
            } else if (c[i] == 'n') { /* not operation */
                if (last_not) {
                    /* double not */
                    expr_size = expr_size - 2;
                    last_not = 0;
                } else {
                    last_not = 1;
                }
            } else { /* and, or */
                if (f_exp != f_size) {
                    LOGVAL(ctx, LYVE_SYNTAX_YANG,
                            "Invalid value \"%s\" of if-feature - missing feature/expression before \"%.*s\" operation.",
                            qname->str, op_len, &c[i]);
                    return LY_EVALID;
                }
                f_exp++;

                /* not a not operation */
                last_not = 0;
            }
            i += op_len;
        } else {
            f_size++;
            last_not = 0;
        }
        expr_size++;

        while (!isspace(c[i])) {
            if (!c[i] || (c[i] == ')') || (c[i] == '(')) {
                i--;
                break;
            }
            i++;
        }
    }
    if (j) {
        /* not matching count of ( and ) */
        LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - non-matching opening and closing parentheses.", qname->str);
        return LY_EVALID;
    }
    if (f_exp != f_size) {
        /* features do not match the needed arguments for the logical operations */
        LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - number of features in expression does not match "
                "the required number of operands for the operations.", qname->str);
        return LY_EVALID;
    }

    if (checkversion || (expr_size > 1)) {
        /* check that we have 1.1 module */
        if (qname->mod->version != LYS_VERSION_1_1) {
            LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - YANG 1.1 expression in YANG 1.0 module.", qname->str);
            return LY_EVALID;
        }
    }

    /* allocate the memory */
    LY_ARRAY_CREATE_RET(ctx, iff->features, f_size, LY_EMEM);
    iff->expr = calloc((j = (expr_size / IFF_RECORDS_IN_BYTE) + ((expr_size % IFF_RECORDS_IN_BYTE) ? 1 : 0)), sizeof *iff->expr);
    stack.stack = malloc(expr_size * sizeof *stack.stack);
    LY_CHECK_ERR_GOTO(!stack.stack || !iff->expr, LOGMEM(ctx); rc = LY_EMEM, error);

    stack.size = expr_size;
    f_size--; expr_size--; /* used as indexes from now */

    for (i--; i >= 0; i--) {
        if (c[i] == ')') {
            /* push it on stack */
            iff_stack_push(&stack, LYS_IFF_RP);
            continue;
        } else if (c[i] == '(') {
            /* pop from the stack into result all operators until ) */
            while ((op = iff_stack_pop(&stack)) != LYS_IFF_RP) {
                iff_setop(iff->expr, op, expr_size--);
            }
            continue;
        } else if (isspace(c[i])) {
            continue;
        }

        /* end of operator or operand -> find beginning and get what is it */
        j = i + 1;
        while (i >= 0 && !isspace(c[i]) && c[i] != '(') {
            i--;
        }
        i++; /* go back by one step */

        if (!strncmp(&c[i], "not", ly_strlen_const("not")) && isspace(c[i + ly_strlen_const("not")])) {
            if (stack.index && (stack.stack[stack.index - 1] == LYS_IFF_NOT)) {
                /* double not */
                iff_stack_pop(&stack);
            } else {
                /* not has the highest priority, so do not pop from the stack
                 * as in case of AND and OR */
                iff_stack_push(&stack, LYS_IFF_NOT);
            }
        } else if (!strncmp(&c[i], "and", ly_strlen_const("and")) && isspace(c[i + ly_strlen_const("and")])) {
            /* as for OR - pop from the stack all operators with the same or higher
             * priority and store them to the result, then push the AND to the stack */
            while (stack.index && stack.stack[stack.index - 1] <= LYS_IFF_AND) {
                op = iff_stack_pop(&stack);
                iff_setop(iff->expr, op, expr_size--);
            }
            iff_stack_push(&stack, LYS_IFF_AND);
        } else if (!strncmp(&c[i], "or", 2) && isspace(c[i + 2])) {
            while (stack.index && stack.stack[stack.index - 1] <= LYS_IFF_OR) {
                op = iff_stack_pop(&stack);
                iff_setop(iff->expr, op, expr_size--);
            }
            iff_stack_push(&stack, LYS_IFF_OR);
        } else {
            /* feature name, length is j - i */

            /* add it to the expression */
            iff_setop(iff->expr, LYS_IFF_F, expr_size--);

            /* now get the link to the feature definition */
            f = lysp_feature_find(qname->mod, &c[i], j - i, 1);
            if (!f) {
                LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - unable to find feature \"%.*s\".",
                        qname->str, (int)(j - i), &c[i]);
                rc = LY_EVALID;
                goto error;
            }
            iff->features[f_size] = f;
            LY_ARRAY_INCREMENT(iff->features);
            f_size--;
        }
    }
    while (stack.index) {
        op = iff_stack_pop(&stack);
        iff_setop(iff->expr, op, expr_size--);
    }

    if (++expr_size || ++f_size) {
        /* not all expected operators and operands found */
        LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - processing error.", qname->str);
        rc = LY_EINT;
    } else {
        rc = LY_SUCCESS;
    }

error:
    /* cleanup */
    iff_stack_clean(&stack);

    return rc;
}

LY_ERR
lys_eval_iffeatures(const struct ly_ctx *ctx, struct lysp_qname *iffeatures, ly_bool *enabled)
{
    LY_ERR ret;
    struct lysc_iffeature iff = {0};

    if (!iffeatures) {
        *enabled = 1;
        return LY_SUCCESS;
    }

    LY_CHECK_RET(lys_compile_iffeature(ctx, iffeatures, &iff));

    ret = lysc_iffeature_value(&iff);
    lysc_iffeature_free((struct ly_ctx *)ctx, &iff);
    if (ret == LY_ENOT) {
        *enabled = 0;
    } else if (ret) {
        return ret;
    } else {
        *enabled = 1;
    }

    return LY_SUCCESS;
}

/**
 * @brief Check whether all enabled features have their if-features satisfied.
 * Enabled features with false if-features are disabled with a warning.
 *
 * @param[in] pmod Parsed module features to check.
 * @return LY_ERR value.
 */
static LY_ERR
lys_check_features(struct lysp_module *pmod)
{
    LY_ERR r;
    uint32_t i = 0;
    struct lysp_feature *f = NULL;

    while ((f = lysp_feature_next(f, pmod, &i))) {
        if (!(f->flags & LYS_FENABLED) || !f->iffeatures) {
            /* disabled feature or no if-features to check */
            continue;
        }

        assert(f->iffeatures_c);
        r = lysc_iffeature_value(f->iffeatures_c);
        if (r == LY_ENOT) {
            LOGWRN(pmod->mod->ctx, "Feature \"%s\" cannot be enabled because its \"if-feature\" is not satisfied.",
                    f->name);

            /* disable feature and re-evaluate all the feature if-features again */
            f->flags &= ~LYS_FENABLED;
            return lys_check_features(pmod);
        } else if (r) {
            return r;
        } /* else if-feature satisfied */
    }

    return LY_SUCCESS;
}

LY_ERR
lys_enable_features(struct lysp_module *pmod, const char **features)
{
    uint32_t i = 0;
    struct lysp_feature *f = 0;

    if (!features || !features[0]) {
        /* keep all features disabled */
        return LY_SUCCESS;
    }

    if (!strcmp(features[0], "*")) {
        /* enable all features */
        while ((f = lysp_feature_next(f, pmod, &i))) {
            f->flags |= LYS_FENABLED;
        }
    } else {
        /* enable selected features */
        for (i = 0; features[i]; ++i) {
            /* find the feature */
            f = lysp_feature_find(pmod, features[i], strlen(features[i]), 0);
            if (!f) {
                LOGERR(pmod->mod->ctx, LY_ENOTFOUND, "Feature \"%s\" not found in module \"%s\".", features[i],
                        pmod->mod->name);
                return LY_ENOTFOUND;
            }

            /* enable feature */
            f->flags |= LYS_FENABLED;
        }
    }

    /* check final features if-feature state */
    return lys_check_features(pmod);
}

LY_ERR
lys_set_features(struct lysp_module *pmod, const char **features)
{
    uint32_t i = 0, j;
    struct lysp_feature *f = 0;
    ly_bool change = 0;

    if (!features) {
        /* do not touch the features */

    } else if (!features[0]) {
        /* disable all the features */
        while ((f = lysp_feature_next(f, pmod, &i))) {
            if (f->flags & LYS_FENABLED) {
                f->flags &= ~LYS_FENABLED;
                change = 1;
            }
        }
    } else if (!strcmp(features[0], "*")) {
        /* enable all the features */
        while ((f = lysp_feature_next(f, pmod, &i))) {
            if (!(f->flags & LYS_FENABLED)) {
                f->flags |= LYS_FENABLED;
                change = 1;
            }
        }
    } else {
        /* enable specific features, disable the rest */
        while ((f = lysp_feature_next(f, pmod, &i))) {
            for (j = 0; features[j]; ++j) {
                if (!strcmp(f->name, features[j])) {
                    break;
                }
            }

            if (features[j] && !(f->flags & LYS_FENABLED)) {
                /* enable */
                f->flags |= LYS_FENABLED;
                change = 1;
            } else if (!features[j] && (f->flags & LYS_FENABLED)) {
                /* disable */
                f->flags &= ~LYS_FENABLED;
                change = 1;
            }
        }
    }

    if (!change) {
        /* features already set correctly */
        return LY_EEXIST;
    }

    /* check final features if-feature state */
    return lys_check_features(pmod);
}

/**
 * @brief Check circular dependency of features - feature MUST NOT reference itself (via their if-feature statement).
 *
 * The function works in the same way as lys_compile_identity_circular_check() with different structures and error messages.
 *
 * @param[in] ctx Compile context for logging.
 * @param[in] feature The feature referenced in if-feature statement (its depfeatures list is being extended by the feature
 *            being currently processed).
 * @param[in] depfeatures The list of depending features of the feature being currently processed (not the one provided as @p feature)
 * @return LY_SUCCESS if everything is ok.
 * @return LY_EVALID if the feature references indirectly itself.
 */
static LY_ERR
lys_compile_feature_circular_check(const struct ly_ctx *ctx, struct lysp_feature *feature, struct lysp_feature **depfeatures)
{
    LY_ERR ret = LY_SUCCESS;
    LY_ARRAY_COUNT_TYPE u, v;
    struct ly_set recursion = {0};
    struct lysp_feature *drv;

    if (!depfeatures) {
        return LY_SUCCESS;
    }

    for (u = 0; u < LY_ARRAY_COUNT(depfeatures); ++u) {
        if (feature == depfeatures[u]) {
            LOGVAL(ctx, LYVE_REFERENCE, "Feature \"%s\" is indirectly referenced from itself.", feature->name);
            ret = LY_EVALID;
            goto cleanup;
        }
        ret = ly_set_add(&recursion, depfeatures[u], 0, NULL);
        LY_CHECK_GOTO(ret, cleanup);
    }

    for (v = 0; v < recursion.count; ++v) {
        drv = recursion.objs[v];
        for (u = 0; u < LY_ARRAY_COUNT(drv->depfeatures); ++u) {
            if (feature == drv->depfeatures[u]) {
                LOGVAL(ctx, LYVE_REFERENCE, "Feature \"%s\" is indirectly referenced from itself.", feature->name);
                ret = LY_EVALID;
                goto cleanup;
            }
            ly_set_add(&recursion, drv->depfeatures[u], 0, NULL);
            LY_CHECK_GOTO(ret, cleanup);
        }
    }

cleanup:
    ly_set_erase(&recursion, NULL);
    return ret;
}

LY_ERR
lys_compile_feature_iffeatures(struct lysp_module *pmod)
{
    LY_ARRAY_COUNT_TYPE u, v;
    struct lysp_feature *f = NULL, **df;
    uint32_t idx = 0;

    while ((f = lysp_feature_next(f, pmod, &idx))) {
        if (!f->iffeatures) {
            continue;
        }

        /* compile if-features */
        LY_ARRAY_CREATE_RET(pmod->mod->ctx, f->iffeatures_c, LY_ARRAY_COUNT(f->iffeatures), LY_EMEM);
        LY_ARRAY_FOR(f->iffeatures, u) {
            LY_ARRAY_INCREMENT(f->iffeatures_c);
            LY_CHECK_RET(lys_compile_iffeature(pmod->mod->ctx, &(f->iffeatures)[u], &(f->iffeatures_c)[u]));
        }
        LY_ARRAY_FOR(f->iffeatures_c, u) {
            LY_ARRAY_FOR(f->iffeatures_c[u].features, v) {
                /* check for circular dependency - direct reference first,... */
                if (f == f->iffeatures_c[u].features[v]) {
                    LOGVAL(pmod->mod->ctx, LYVE_REFERENCE, "Feature \"%s\" is referenced from itself.", f->name);
                    return LY_EVALID;
                }
                /* ... and indirect circular reference */
                LY_CHECK_RET(lys_compile_feature_circular_check(pmod->mod->ctx, f->iffeatures_c[u].features[v], f->depfeatures));

                /* add itself into the dependants list */
                LY_ARRAY_NEW_RET(pmod->mod->ctx, f->iffeatures_c[u].features[v]->depfeatures, df, LY_EMEM);
                *df = f;
            }
        }
    }

    return LY_SUCCESS;
}

void
lys_free_feature_iffeatures(struct lysp_module *pmod)
{
    struct lysp_feature *f = NULL;
    uint32_t idx = 0;

    while ((f = lysp_feature_next(f, pmod, &idx))) {
        FREE_ARRAY(pmod->mod->ctx, f->iffeatures_c, lysc_iffeature_free);
        f->iffeatures_c = NULL;
        LY_ARRAY_FREE(f->depfeatures);
        f->depfeatures = NULL;
    }
}
