/*
 * Copyright 2004-2019 the Pacemaker project contributors
 *
 * The version control history for this file may have further details.
 *
 * This source code is licensed under the GNU Lesser General Public License
 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
 */

#include <crm_internal.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>

#include <glib.h>

#include <crm/pengine/rules.h>
#include <crm/pengine/internal.h>

#include <sys/types.h>
#include <regex.h>
#include <ctype.h>

CRM_TRACE_INIT_DATA(pe_rules);

crm_time_t *parse_xml_duration(crm_time_t * start, xmlNode * duration_spec);

gboolean test_date_expression(xmlNode * time_expr, crm_time_t * now);
gboolean cron_range_satisfied(crm_time_t * now, xmlNode * cron_spec);
gboolean test_attr_expression(xmlNode * expr, GHashTable * hash, crm_time_t * now);
gboolean pe_test_attr_expression_full(xmlNode * expr, GHashTable * hash, crm_time_t * now, pe_match_data_t * match_data);
gboolean test_role_expression(xmlNode * expr, enum rsc_role_e role, crm_time_t * now);

gboolean
test_ruleset(xmlNode * ruleset, GHashTable * node_hash, crm_time_t * now)
{
    gboolean ruleset_default = TRUE;
    xmlNode *rule = NULL;

    for (rule = __xml_first_child_element(ruleset); rule != NULL;
         rule = __xml_next_element(rule)) {

        if (crm_str_eq((const char *)rule->name, XML_TAG_RULE, TRUE)) {
            ruleset_default = FALSE;
            if (test_rule(rule, node_hash, RSC_ROLE_UNKNOWN, now)) {
                return TRUE;
            }
        }
    }

    return ruleset_default;
}

gboolean
test_rule(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now)
{
    return pe_test_rule_full(rule, node_hash, role, now, NULL);
}

gboolean
pe_test_rule_re(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now, pe_re_match_data_t * re_match_data)
{
    pe_match_data_t match_data = {
                                    .re = re_match_data,
                                    .params = NULL,
                                    .meta = NULL,
                                 };
    return pe_test_rule_full(rule, node_hash, role, now, &match_data);
}

gboolean
pe_test_rule_full(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now, pe_match_data_t * match_data)
{
    xmlNode *expr = NULL;
    gboolean test = TRUE;
    gboolean empty = TRUE;
    gboolean passed = TRUE;
    gboolean do_and = TRUE;
    const char *value = NULL;

    rule = expand_idref(rule, NULL);
    value = crm_element_value(rule, XML_RULE_ATTR_BOOLEAN_OP);
    if (safe_str_eq(value, "or")) {
        do_and = FALSE;
        passed = FALSE;
    }

    crm_trace("Testing rule %s", ID(rule));
    for (expr = __xml_first_child_element(rule); expr != NULL;
         expr = __xml_next_element(expr)) {

        test = pe_test_expression_full(expr, node_hash, role, now, match_data);
        empty = FALSE;

        if (test && do_and == FALSE) {
            crm_trace("Expression %s/%s passed", ID(rule), ID(expr));
            return TRUE;

        } else if (test == FALSE && do_and) {
            crm_trace("Expression %s/%s failed", ID(rule), ID(expr));
            return FALSE;
        }
    }

    if (empty) {
        crm_err("Invalid Rule %s: rules must contain at least one expression", ID(rule));
    }

    crm_trace("Rule %s %s", ID(rule), passed ? "passed" : "failed");
    return passed;
}

gboolean
test_expression(xmlNode * expr, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now)
{
    return pe_test_expression_full(expr, node_hash, role, now, NULL);
}

gboolean
pe_test_expression_re(xmlNode * expr, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now, pe_re_match_data_t * re_match_data)
{
    pe_match_data_t match_data = {
                                    .re = re_match_data,
                                    .params = NULL,
                                    .meta = NULL,
                                 };
    return pe_test_expression_full(expr, node_hash, role, now, &match_data);
}

gboolean
pe_test_expression_full(xmlNode * expr, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now, pe_match_data_t * match_data)
{
    gboolean accept = FALSE;
    const char *uname = NULL;

    switch (find_expression_type(expr)) {
        case nested_rule:
            accept = pe_test_rule_full(expr, node_hash, role, now, match_data);
            break;
        case attr_expr:
        case loc_expr:
            /* these expressions can never succeed if there is
             * no node to compare with
             */
            if (node_hash != NULL) {
                accept = pe_test_attr_expression_full(expr, node_hash, now, match_data);
            }
            break;

        case time_expr:
            accept = test_date_expression(expr, now);
            break;

        case role_expr:
            accept = test_role_expression(expr, role, now);
            break;

#ifdef ENABLE_VERSIONED_ATTRS
        case version_expr:
            if (node_hash && g_hash_table_lookup_extended(node_hash,
                                                          CRM_ATTR_RA_VERSION,
                                                          NULL, NULL)) {
                accept = test_attr_expression(expr, node_hash, now);
            } else {
                // we are going to test it when we have ra-version
                accept = TRUE;
            }
            break;
#endif

        default:
            CRM_CHECK(FALSE /* bad type */ , return FALSE);
            accept = FALSE;
    }
    if (node_hash) {
        uname = g_hash_table_lookup(node_hash, CRM_ATTR_UNAME);
    }

    crm_trace("Expression %s %s on %s",
              ID(expr), accept ? "passed" : "failed", uname ? uname : "all nodes");
    return accept;
}

enum expression_type
find_expression_type(xmlNode * expr)
{
    const char *tag = NULL;
    const char *attr = NULL;

    attr = crm_element_value(expr, XML_EXPR_ATTR_ATTRIBUTE);
    tag = crm_element_name(expr);

    if (safe_str_eq(tag, "date_expression")) {
        return time_expr;

    } else if (safe_str_eq(tag, XML_TAG_RULE)) {
        return nested_rule;

    } else if (safe_str_neq(tag, "expression")) {
        return not_expr;

    } else if (safe_str_eq(attr, CRM_ATTR_UNAME)
               || safe_str_eq(attr, CRM_ATTR_KIND)
               || safe_str_eq(attr, CRM_ATTR_ID)) {
        return loc_expr;

    } else if (safe_str_eq(attr, CRM_ATTR_ROLE)) {
        return role_expr;

#ifdef ENABLE_VERSIONED_ATTRS
    } else if (safe_str_eq(attr, CRM_ATTR_RA_VERSION)) {
        return version_expr;
#endif
    }

    return attr_expr;
}

gboolean
test_role_expression(xmlNode * expr, enum rsc_role_e role, crm_time_t * now)
{
    gboolean accept = FALSE;
    const char *op = NULL;
    const char *value = NULL;

    if (role == RSC_ROLE_UNKNOWN) {
        return accept;
    }

    value = crm_element_value(expr, XML_EXPR_ATTR_VALUE);
    op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION);

    if (safe_str_eq(op, "defined")) {
        if (role > RSC_ROLE_STARTED) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "not_defined")) {
        if (role < RSC_ROLE_SLAVE && role > RSC_ROLE_UNKNOWN) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "eq")) {
        if (text2role(value) == role) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "ne")) {
        /* we will only test "ne" wtih master/slave roles style */
        if (role < RSC_ROLE_SLAVE && role > RSC_ROLE_UNKNOWN) {
            accept = FALSE;

        } else if (text2role(value) != role) {
            accept = TRUE;
        }
    }
    return accept;
}

gboolean
test_attr_expression(xmlNode * expr, GHashTable * hash, crm_time_t * now)
{
    return pe_test_attr_expression_full(expr, hash, now, NULL);
}

gboolean
pe_test_attr_expression_full(xmlNode * expr, GHashTable * hash, crm_time_t * now, pe_match_data_t * match_data)
{
    gboolean accept = FALSE;
    gboolean attr_allocated = FALSE;
    int cmp = 0;
    const char *h_val = NULL;
    GHashTable *table = NULL;

    const char *op = NULL;
    const char *type = NULL;
    const char *attr = NULL;
    const char *value = NULL;
    const char *value_source = NULL;

    attr = crm_element_value(expr, XML_EXPR_ATTR_ATTRIBUTE);
    op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION);
    value = crm_element_value(expr, XML_EXPR_ATTR_VALUE);
    type = crm_element_value(expr, XML_EXPR_ATTR_TYPE);
    value_source = crm_element_value(expr, XML_EXPR_ATTR_VALUE_SOURCE);

    if (attr == NULL || op == NULL) {
        pe_err("Invalid attribute or operation in expression"
               " (\'%s\' \'%s\' \'%s\')", crm_str(attr), crm_str(op), crm_str(value));
        return FALSE;
    }

    if (match_data) {
        if (match_data->re) {
            char *resolved_attr = pe_expand_re_matches(attr, match_data->re);

            if (resolved_attr) {
                attr = (const char *) resolved_attr;
                attr_allocated = TRUE;
            }
        }

        if (safe_str_eq(value_source, "param")) {
            table = match_data->params;
        } else if (safe_str_eq(value_source, "meta")) {
            table = match_data->meta;
        }
    }

    if (table) {
        const char *param_name = value;
        const char *param_value = NULL;

        if (param_name && param_name[0]) {
            if ((param_value = (const char *)g_hash_table_lookup(table, param_name))) {
                value = param_value;
            }
        }
    }

    if (hash != NULL) {
        h_val = (const char *)g_hash_table_lookup(hash, attr);
    }

    if (attr_allocated) {
        free((char *)attr);
        attr = NULL;
    }

    if (value != NULL && h_val != NULL) {
        if (type == NULL) {
            if (safe_str_eq(op, "lt")
                || safe_str_eq(op, "lte")
                || safe_str_eq(op, "gt")
                || safe_str_eq(op, "gte")) {
                type = "number";

            } else {
                type = "string";
            }
            crm_trace("Defaulting to %s based comparison for '%s' op", type, op);
        }

        if (safe_str_eq(type, "string")) {
            cmp = strcasecmp(h_val, value);

        } else if (safe_str_eq(type, "number")) {
            int h_val_f = crm_parse_int(h_val, NULL);
            int value_f = crm_parse_int(value, NULL);

            if (h_val_f < value_f) {
                cmp = -1;
            } else if (h_val_f > value_f) {
                cmp = 1;
            } else {
                cmp = 0;
            }

        } else if (safe_str_eq(type, "version")) {
            cmp = compare_version(h_val, value);

        }

    } else if (value == NULL && h_val == NULL) {
        cmp = 0;
    } else if (value == NULL) {
        cmp = 1;
    } else {
        cmp = -1;
    }

    if (safe_str_eq(op, "defined")) {
        if (h_val != NULL) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "not_defined")) {
        if (h_val == NULL) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "eq")) {
        if ((h_val == value) || cmp == 0) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "ne")) {
        if ((h_val == NULL && value != NULL)
            || (h_val != NULL && value == NULL)
            || cmp != 0) {
            accept = TRUE;
        }

    } else if (value == NULL || h_val == NULL) {
        // The comparison is meaningless from this point on
        accept = FALSE;

    } else if (safe_str_eq(op, "lt")) {
        if (cmp < 0) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "lte")) {
        if (cmp <= 0) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "gt")) {
        if (cmp > 0) {
            accept = TRUE;
        }

    } else if (safe_str_eq(op, "gte")) {
        if (cmp >= 0) {
            accept = TRUE;
        }
    }

    return accept;
}

/* As per the nethack rules:
 *
 * moon period = 29.53058 days ~= 30, year = 365.2422 days
 * days moon phase advances on first day of year compared to preceding year
 *      = 365.2422 - 12*29.53058 ~= 11
 * years in Metonic cycle (time until same phases fall on the same days of
 *      the month) = 18.6 ~= 19
 * moon phase on first day of year (epact) ~= (11*(year%19) + 29) % 30
 *      (29 as initial condition)
 * current phase in days = first day phase + days elapsed in year
 * 6 moons ~= 177 days
 * 177 ~= 8 reported phases * 22
 * + 11/22 for rounding
 *
 * 0-7, with 0: new, 4: full
 */

static int
phase_of_the_moon(crm_time_t * now)
{
    uint32_t epact, diy, goldn;
    uint32_t y;

    crm_time_get_ordinal(now, &y, &diy);

    goldn = (y % 19) + 1;
    epact = (11 * goldn + 18) % 30;
    if ((epact == 25 && goldn > 11) || epact == 24)
        epact++;

    return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7);
}

static gboolean
decodeNVpair(const char *srcstring, char separator, char **name, char **value)
{
    int lpc = 0;
    int len = 0;
    const char *temp = NULL;

    CRM_ASSERT(name != NULL && value != NULL);
    *name = NULL;
    *value = NULL;

    crm_trace("Attempting to decode: [%s]", srcstring);
    if (srcstring != NULL) {
        len = strlen(srcstring);
        while (lpc <= len) {
            if (srcstring[lpc] == separator) {
                *name = calloc(1, lpc + 1);
                if (*name == NULL) {
                    break;      /* and return FALSE */
                }
                memcpy(*name, srcstring, lpc);
                (*name)[lpc] = '\0';

/* this sucks but as the strtok manpage says..
 * it *is* a bug
 */
                len = len - lpc;
                len--;
                if (len <= 0) {
                    *value = NULL;
                } else {

                    *value = calloc(1, len + 1);
                    if (*value == NULL) {
                        break;  /* and return FALSE */
                    }
                    temp = srcstring + lpc + 1;
                    memcpy(*value, temp, len);
                    (*value)[len] = '\0';
                }
                return TRUE;
            }
            lpc++;
        }
    }

    if (*name != NULL) {
        free(*name);
        *name = NULL;
    }
    *name = NULL;
    *value = NULL;

    return FALSE;
}

#define cron_check(xml_field, time_field)				\
    value = crm_element_value(cron_spec, xml_field);			\
    if(value != NULL) {							\
	gboolean pass = TRUE;						\
	decodeNVpair(value, '-', &value_low, &value_high);		\
	if(value_low == NULL) {						\
	    value_low = strdup(value);				\
	}								\
	value_low_i = crm_parse_int(value_low, "0");			\
	value_high_i = crm_parse_int(value_high, "-1");			\
	if(value_high_i < 0) {						\
	    if(value_low_i != time_field) {				\
		pass = FALSE;						\
	    }								\
	} else if(value_low_i > time_field) {				\
	    pass = FALSE;						\
	} else if(value_high_i < time_field) {				\
	    pass = FALSE;						\
	}								\
	free(value_low);						\
	free(value_high);						\
	if(pass == FALSE) {						\
	    crm_debug("Condition '%s' in %s: failed", value, xml_field); \
	    return pass;						\
	}								\
	crm_debug("Condition '%s' in %s: passed", value, xml_field);	\
    }

gboolean
cron_range_satisfied(crm_time_t * now, xmlNode * cron_spec)
{
    const char *value = NULL;
    char *value_low = NULL;
    char *value_high = NULL;

    int value_low_i = 0;
    int value_high_i = 0;

    uint32_t h, m, s, y, d, w;

    CRM_CHECK(now != NULL, return FALSE);

    crm_time_get_timeofday(now, &h, &m, &s);

    cron_check("seconds", s);
    cron_check("minutes", m);
    cron_check("hours", h);

    crm_time_get_gregorian(now, &y, &m, &d);

    cron_check("monthdays", d);
    cron_check("months", m);
    cron_check("years", y);

    crm_time_get_ordinal(now, &y, &d);

    cron_check("yeardays", d);

    crm_time_get_isoweek(now, &y, &w, &d);

    cron_check("weekyears", y);
    cron_check("weeks", w);
    cron_check("weekdays", d);

    cron_check("moon", phase_of_the_moon(now));

    return TRUE;
}

#define update_field(xml_field, time_fn)			\
    value = crm_element_value(duration_spec, xml_field);	\
    if(value != NULL) {						\
	int value_i = crm_parse_int(value, "0");		\
	time_fn(end, value_i);					\
    }

crm_time_t *
parse_xml_duration(crm_time_t * start, xmlNode * duration_spec)
{
    crm_time_t *end = NULL;
    const char *value = NULL;

    end = crm_time_new(NULL);
    crm_time_set(end, start);

    update_field("years", crm_time_add_years);
    update_field("months", crm_time_add_months);
    update_field("weeks", crm_time_add_weeks);
    update_field("days", crm_time_add_days);
    update_field("hours", crm_time_add_hours);
    update_field("minutes", crm_time_add_minutes);
    update_field("seconds", crm_time_add_seconds);

    return end;
}

gboolean
test_date_expression(xmlNode * time_expr, crm_time_t * now)
{
    crm_time_t *start = NULL;
    crm_time_t *end = NULL;
    const char *value = NULL;
    const char *op = crm_element_value(time_expr, "operation");

    xmlNode *duration_spec = NULL;
    xmlNode *date_spec = NULL;

    gboolean passed = FALSE;

    crm_trace("Testing expression: %s", ID(time_expr));

    duration_spec = first_named_child(time_expr, "duration");
    date_spec = first_named_child(time_expr, "date_spec");

    value = crm_element_value(time_expr, "start");
    if (value != NULL) {
        start = crm_time_new(value);
    }
    value = crm_element_value(time_expr, "end");
    if (value != NULL) {
        end = crm_time_new(value);
    }

    if (start != NULL && end == NULL && duration_spec != NULL) {
        end = parse_xml_duration(start, duration_spec);
    }
    if (op == NULL) {
        op = "in_range";
    }

    if (safe_str_eq(op, "date_spec") || safe_str_eq(op, "in_range")) {
        if (start != NULL && crm_time_compare(start, now) > 0) {
            passed = FALSE;
        } else if (end != NULL && crm_time_compare(end, now) < 0) {
            passed = FALSE;
        } else if (safe_str_eq(op, "in_range")) {
            passed = TRUE;
        } else {
            passed = cron_range_satisfied(now, date_spec);
        }

    } else if (safe_str_eq(op, "gt") && crm_time_compare(start, now) < 0) {
        passed = TRUE;

    } else if (safe_str_eq(op, "lt") && crm_time_compare(end, now) > 0) {
        passed = TRUE;

    } else if (safe_str_eq(op, "eq") && crm_time_compare(start, now) == 0) {
        passed = TRUE;

    } else if (safe_str_eq(op, "neq") && crm_time_compare(start, now) != 0) {
        passed = TRUE;
    }

    crm_time_free(start);
    crm_time_free(end);
    return passed;
}

typedef struct sorted_set_s {
    int score;
    const char *name;
    const char *special_name;
    xmlNode *attr_set;
} sorted_set_t;

static gint
sort_pairs(gconstpointer a, gconstpointer b)
{
    const sorted_set_t *pair_a = a;
    const sorted_set_t *pair_b = b;

    if (a == NULL && b == NULL) {
        return 0;
    } else if (a == NULL) {
        return 1;
    } else if (b == NULL) {
        return -1;
    }

    if (safe_str_eq(pair_a->name, pair_a->special_name)) {
        return -1;

    } else if (safe_str_eq(pair_b->name, pair_a->special_name)) {
        return 1;
    }

    if (pair_a->score < pair_b->score) {
        return 1;
    } else if (pair_a->score > pair_b->score) {
        return -1;
    }
    return 0;
}

static void
populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlNode * top)
{
    const char *name = NULL;
    const char *value = NULL;
    const char *old_value = NULL;
    xmlNode *list = nvpair_list;
    xmlNode *an_attr = NULL;

    name = crm_element_name(list->children);
    if (safe_str_eq(XML_TAG_ATTRS, name)) {
        list = list->children;
    }

    for (an_attr = __xml_first_child_element(list); an_attr != NULL;
         an_attr = __xml_next_element(an_attr)) {

        if (crm_str_eq((const char *)an_attr->name, XML_CIB_TAG_NVPAIR, TRUE)) {
            xmlNode *ref_nvpair = expand_idref(an_attr, top);

            name = crm_element_value(an_attr, XML_NVPAIR_ATTR_NAME);
            if (name == NULL) {
                name = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_NAME);
            }

            crm_trace("Setting attribute: %s", name);
            value = crm_element_value(an_attr, XML_NVPAIR_ATTR_VALUE);
            if (value == NULL) {
                value = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_VALUE);
            }

            if (name == NULL || value == NULL) {
                continue;

            }

            old_value = g_hash_table_lookup(hash, name);

            if (safe_str_eq(value, "#default")) {
                if (old_value) {
                    crm_trace("Removing value for %s (%s)", name, value);
                    g_hash_table_remove(hash, name);
                }
                continue;

            } else if (old_value == NULL) {
                g_hash_table_insert(hash, strdup(name), strdup(value));

            } else if (overwrite) {
                crm_debug("Overwriting value of %s: %s -> %s", name, old_value, value);
                g_hash_table_replace(hash, strdup(name), strdup(value));
            }
        }
    }
}

#ifdef ENABLE_VERSIONED_ATTRS
static xmlNode*
get_versioned_rule(xmlNode * attr_set)
{
    xmlNode * rule = NULL;
    xmlNode * expr = NULL;

    for (rule = __xml_first_child_element(attr_set); rule != NULL;
         rule = __xml_next_element(rule)) {

        if (crm_str_eq((const char *)rule->name, XML_TAG_RULE, TRUE)) {
            for (expr = __xml_first_child_element(rule); expr != NULL;
                 expr = __xml_next_element(expr)) {

                if (find_expression_type(expr) == version_expr) {
                    return rule;
                }
            }
        }
    }

    return NULL;
}

static void
add_versioned_attributes(xmlNode * attr_set, xmlNode * versioned_attrs)
{
    xmlNode *attr_set_copy = NULL;
    xmlNode *rule = NULL;
    xmlNode *expr = NULL;

    if (!attr_set || !versioned_attrs) {
        return;
    }

    attr_set_copy = copy_xml(attr_set);

    rule = get_versioned_rule(attr_set_copy);
    if (!rule) {
        free_xml(attr_set_copy);
        return;
    }

    expr = __xml_first_child_element(rule);
    while (expr != NULL) {
        if (find_expression_type(expr) != version_expr) {
            xmlNode *node = expr;

            expr = __xml_next_element(expr);
            free_xml(node);
        } else {
            expr = __xml_next_element(expr);
        }
    }

    add_node_nocopy(versioned_attrs, NULL, attr_set_copy);
}
#endif

typedef struct unpack_data_s {
    gboolean overwrite;
    GHashTable *node_hash;
    void *hash;
    crm_time_t *now;
    xmlNode *top;
} unpack_data_t;

static void
unpack_attr_set(gpointer data, gpointer user_data)
{
    sorted_set_t *pair = data;
    unpack_data_t *unpack_data = user_data;

    if (test_ruleset(pair->attr_set, unpack_data->node_hash, unpack_data->now) == FALSE) {
        return;
    }

#ifdef ENABLE_VERSIONED_ATTRS
    if (get_versioned_rule(pair->attr_set) && !(unpack_data->node_hash &&
        g_hash_table_lookup_extended(unpack_data->node_hash,
                                     CRM_ATTR_RA_VERSION, NULL, NULL))) {
        // we haven't actually tested versioned expressions yet
        return;
    }
#endif

    crm_trace("Adding attributes from %s", pair->name);
    populate_hash(pair->attr_set, unpack_data->hash, unpack_data->overwrite, unpack_data->top);
}

#ifdef ENABLE_VERSIONED_ATTRS
static void
unpack_versioned_attr_set(gpointer data, gpointer user_data)
{
    sorted_set_t *pair = data;
    unpack_data_t *unpack_data = user_data;

    if (test_ruleset(pair->attr_set, unpack_data->node_hash, unpack_data->now) == FALSE) {
        return;
    }

    add_versioned_attributes(pair->attr_set, unpack_data->hash);
}
#endif

static GListPtr
make_pairs_and_populate_data(xmlNode * top, xmlNode * xml_obj, const char *set_name,
                             GHashTable * node_hash, void * hash, const char *always_first,
                             gboolean overwrite, crm_time_t * now, unpack_data_t * data)
{
    GListPtr unsorted = NULL;
    const char *score = NULL;
    sorted_set_t *pair = NULL;
    xmlNode *attr_set = NULL;

    if (xml_obj == NULL) {
        crm_trace("No instance attributes");
        return NULL;
    }

    crm_trace("Checking for attributes");
    for (attr_set = __xml_first_child_element(xml_obj); attr_set != NULL;
         attr_set = __xml_next_element(attr_set)) {

        /* Uncertain if set_name == NULL check is strictly necessary here */
        if (set_name == NULL || crm_str_eq((const char *)attr_set->name, set_name, TRUE)) {
            pair = NULL;
            attr_set = expand_idref(attr_set, top);
            if (attr_set == NULL) {
                continue;
            }

            pair = calloc(1, sizeof(sorted_set_t));
            pair->name = ID(attr_set);
            pair->special_name = always_first;
            pair->attr_set = attr_set;

            score = crm_element_value(attr_set, XML_RULE_ATTR_SCORE);
            pair->score = char2score(score);

            unsorted = g_list_prepend(unsorted, pair);
        }
    }

    if (pair != NULL) {
        data->hash = hash;
        data->node_hash = node_hash;
        data->now = now;
        data->overwrite = overwrite;
        data->top = top;
    }

    if (unsorted) {
        return g_list_sort(unsorted, sort_pairs);
    }

    return NULL;
}

void
unpack_instance_attributes(xmlNode * top, xmlNode * xml_obj, const char *set_name,
                           GHashTable * node_hash, GHashTable * hash, const char *always_first,
                           gboolean overwrite, crm_time_t * now)
{
    unpack_data_t data;
    GListPtr pairs = make_pairs_and_populate_data(top, xml_obj, set_name, node_hash, hash,
                                                  always_first, overwrite, now, &data);

    if (pairs) {
        g_list_foreach(pairs, unpack_attr_set, &data);
        g_list_free_full(pairs, free);
    }
}

#ifdef ENABLE_VERSIONED_ATTRS
void
pe_unpack_versioned_attributes(xmlNode * top, xmlNode * xml_obj, const char *set_name,
                               GHashTable * node_hash, xmlNode * hash, crm_time_t * now)
{
    unpack_data_t data;
    GListPtr pairs = make_pairs_and_populate_data(top, xml_obj, set_name, node_hash, hash,
                                                  NULL, FALSE, now, &data);

    if (pairs) {
        g_list_foreach(pairs, unpack_versioned_attr_set, &data);
        g_list_free_full(pairs, free);
    }
}
#endif

char *
pe_expand_re_matches(const char *string, pe_re_match_data_t *match_data)
{
    size_t len = 0;
    int i;
    const char *p, *last_match_index;
    char *p_dst, *result = NULL;

    if (!string || string[0] == '\0' || !match_data) {
        return NULL;
    }

    p = last_match_index = string;

    while (*p) {
        if (*p == '%' && *(p + 1) && isdigit(*(p + 1))) {
            i = *(p + 1) - '0';
            if (match_data->nregs >= i && match_data->pmatch[i].rm_so != -1 &&
                match_data->pmatch[i].rm_eo > match_data->pmatch[i].rm_so) {
                len += p - last_match_index + (match_data->pmatch[i].rm_eo - match_data->pmatch[i].rm_so);
                last_match_index = p + 2;
            }
            p++;
        }
        p++;
    }
    len += p - last_match_index + 1;

    /* FIXME: Excessive? */
    if (len - 1 <= 0) {
        return NULL;
    }

    p_dst = result = calloc(1, len);
    p = string;

    while (*p) {
        if (*p == '%' && *(p + 1) && isdigit(*(p + 1))) {
            i = *(p + 1) - '0';
            if (match_data->nregs >= i && match_data->pmatch[i].rm_so != -1 &&
                match_data->pmatch[i].rm_eo > match_data->pmatch[i].rm_so) {
                /* rm_eo can be equal to rm_so, but then there is nothing to do */
                int match_len = match_data->pmatch[i].rm_eo - match_data->pmatch[i].rm_so;
                memcpy(p_dst, match_data->string + match_data->pmatch[i].rm_so, match_len);
                p_dst += match_len;
            }
            p++;
        } else {
            *(p_dst) = *(p);
            p_dst++;
        }
        p++;
    }

    return result;
}

#ifdef ENABLE_VERSIONED_ATTRS
GHashTable*
pe_unpack_versioned_parameters(xmlNode *versioned_params, const char *ra_version)
{
    GHashTable *hash = crm_str_table_new();

    if (versioned_params && ra_version) {
        GHashTable *node_hash = crm_str_table_new();
        xmlNode *attr_set = __xml_first_child_element(versioned_params);

        if (attr_set) {
            g_hash_table_insert(node_hash, strdup(CRM_ATTR_RA_VERSION),
                                strdup(ra_version));
            unpack_instance_attributes(NULL, versioned_params, crm_element_name(attr_set),
                                       node_hash, hash, NULL, FALSE, NULL);
        }

        g_hash_table_destroy(node_hash);
    }

    return hash;
}
#endif
