/*
 * Copyright (C) 2014 Gao,Yan <ygao@suse.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <crm_internal.h>
#include <crm/msg_xml.h>
#include <allocate.h>
#include <utils.h>

static GListPtr find_colocated_rscs(GListPtr colocated_rscs, resource_t * rsc,
                                    resource_t * orig_rsc);

static GListPtr group_find_colocated_rscs(GListPtr colocated_rscs, resource_t * rsc,
                                          resource_t * orig_rsc);

static void group_add_unallocated_utilization(GHashTable * all_utilization, resource_t * rsc,
                                              GListPtr all_rscs);

struct compare_data {
    const node_t *node1;
    const node_t *node2;
    int result;
};

static void
do_compare_capacity1(gpointer key, gpointer value, gpointer user_data)
{
    int node1_capacity = 0;
    int node2_capacity = 0;
    struct compare_data *data = user_data;

    node1_capacity = crm_parse_int(value, "0");
    node2_capacity =
        crm_parse_int(g_hash_table_lookup(data->node2->details->utilization, key), "0");

    if (node1_capacity > node2_capacity) {
        data->result--;
    } else if (node1_capacity < node2_capacity) {
        data->result++;
    }
}

static void
do_compare_capacity2(gpointer key, gpointer value, gpointer user_data)
{
    int node1_capacity = 0;
    int node2_capacity = 0;
    struct compare_data *data = user_data;

    if (g_hash_table_lookup_extended(data->node1->details->utilization, key, NULL, NULL)) {
        return;
    }

    node1_capacity = 0;
    node2_capacity = crm_parse_int(value, "0");

    if (node1_capacity > node2_capacity) {
        data->result--;
    } else if (node1_capacity < node2_capacity) {
        data->result++;
    }
}

/* rc < 0 if 'node1' has more capacity remaining
 * rc > 0 if 'node1' has less capacity remaining
 */
int
compare_capacity(const node_t * node1, const node_t * node2)
{
    struct compare_data data;

    data.node1 = node1;
    data.node2 = node2;
    data.result = 0;

    g_hash_table_foreach(node1->details->utilization, do_compare_capacity1, &data);
    g_hash_table_foreach(node2->details->utilization, do_compare_capacity2, &data);

    return data.result;
}

struct calculate_data {
    GHashTable *current_utilization;
    gboolean plus;
};

static void
do_calculate_utilization(gpointer key, gpointer value, gpointer user_data)
{
    const char *current = NULL;
    char *result = NULL;
    struct calculate_data *data = user_data;

    current = g_hash_table_lookup(data->current_utilization, key);
    if (data->plus) {
        result = crm_itoa(crm_parse_int(current, "0") + crm_parse_int(value, "0"));
        g_hash_table_replace(data->current_utilization, strdup(key), result);

    } else if (current) {
        result = crm_itoa(crm_parse_int(current, "0") - crm_parse_int(value, "0"));
        g_hash_table_replace(data->current_utilization, strdup(key), result);
    }
}

/* Specify 'plus' to FALSE when allocating
 * Otherwise to TRUE when deallocating
 */
void
calculate_utilization(GHashTable * current_utilization,
                      GHashTable * utilization, gboolean plus)
{
    struct calculate_data data;

    data.current_utilization = current_utilization;
    data.plus = plus;

    g_hash_table_foreach(utilization, do_calculate_utilization, &data);
}


struct capacity_data {
    node_t *node;
    const char *rsc_id;
    gboolean is_enough;
};

static void
check_capacity(gpointer key, gpointer value, gpointer user_data)
{
    int required = 0;
    int remaining = 0;
    struct capacity_data *data = user_data;

    required = crm_parse_int(value, "0");
    remaining = crm_parse_int(g_hash_table_lookup(data->node->details->utilization, key), "0");

    if (required > remaining) {
        CRM_ASSERT(data->rsc_id);
        CRM_ASSERT(data->node);

        crm_debug("Node %s does not have enough %s for %s: required=%d remaining=%d",
                  data->node->details->uname, (char *)key, data->rsc_id, required, remaining);
        data->is_enough = FALSE;
    }
}

static gboolean
have_enough_capacity(node_t * node, const char * rsc_id, GHashTable * utilization)
{
    struct capacity_data data;

    data.node = node;
    data.rsc_id = rsc_id;
    data.is_enough = TRUE;

    g_hash_table_foreach(utilization, check_capacity, &data);

    return data.is_enough;
}


static void
native_add_unallocated_utilization(GHashTable * all_utilization, resource_t * rsc)
{
    if(is_set(rsc->flags, pe_rsc_provisional) == FALSE) {
        return;
    }

    calculate_utilization(all_utilization, rsc->utilization, TRUE);
}

static void
add_unallocated_utilization(GHashTable * all_utilization, resource_t * rsc,
                    GListPtr all_rscs, resource_t * orig_rsc)
{
    if(is_set(rsc->flags, pe_rsc_provisional) == FALSE) {
        return;
    }

    if (rsc->variant == pe_native) {
        pe_rsc_trace(orig_rsc, "%s: Adding %s as colocated utilization",
                     orig_rsc->id, rsc->id);
        native_add_unallocated_utilization(all_utilization, rsc);

    } else if (rsc->variant == pe_group) {
        pe_rsc_trace(orig_rsc, "%s: Adding %s as colocated utilization",
                     orig_rsc->id, rsc->id);
        group_add_unallocated_utilization(all_utilization, rsc, all_rscs);

    } else if (pe_rsc_is_clone(rsc)) {
        GListPtr gIter1 = NULL;
        gboolean existing = FALSE;

        /* Check if there's any child already existing in the list */
        gIter1 = rsc->children;
        for (; gIter1 != NULL; gIter1 = gIter1->next) {
            resource_t *child = (resource_t *) gIter1->data;
            GListPtr gIter2 = NULL;

            if (g_list_find(all_rscs, child)) {
                existing = TRUE;

            } else {
                /* Check if there's any child of another cloned group already existing in the list */
                gIter2 = child->children;
                for (; gIter2 != NULL; gIter2 = gIter2->next) {
                    resource_t *grandchild = (resource_t *) gIter2->data;

                    if (g_list_find(all_rscs, grandchild)) {
                        pe_rsc_trace(orig_rsc, "%s: Adding %s as colocated utilization",
                                     orig_rsc->id, child->id);
                        add_unallocated_utilization(all_utilization, child, all_rscs, orig_rsc);
                        existing = TRUE;
                        break;
                    }
                }
            }
        }

        // rsc->children is always non-NULL but this makes static analysis happy
        if (!existing && (rsc->children != NULL)) {
            resource_t *first_child = (resource_t *) rsc->children->data;

            pe_rsc_trace(orig_rsc, "%s: Adding %s as colocated utilization",
                         orig_rsc->id, ID(first_child->xml));
            add_unallocated_utilization(all_utilization, first_child, all_rscs, orig_rsc);
        }
    }
}

static GHashTable *
sum_unallocated_utilization(resource_t * rsc, GListPtr colocated_rscs)
{
    GListPtr gIter = NULL;
    GListPtr all_rscs = NULL;
    GHashTable *all_utilization = crm_str_table_new();

    all_rscs = g_list_copy(colocated_rscs);
    if (g_list_find(all_rscs, rsc) == FALSE) {
        all_rscs = g_list_append(all_rscs, rsc);
    }

    for (gIter = all_rscs; gIter != NULL; gIter = gIter->next) {
        resource_t *listed_rsc = (resource_t *) gIter->data;

        if(is_set(listed_rsc->flags, pe_rsc_provisional) == FALSE) {
            continue;
        }

        pe_rsc_trace(rsc, "%s: Processing unallocated colocated %s", rsc->id, listed_rsc->id);
        add_unallocated_utilization(all_utilization, listed_rsc, all_rscs, rsc);
    }

    g_list_free(all_rscs);

    return all_utilization;
}

static GListPtr
find_colocated_rscs(GListPtr colocated_rscs, resource_t * rsc, resource_t * orig_rsc)
{
    GListPtr gIter = NULL;

    if (rsc == NULL) {
        return colocated_rscs;

    } else if (g_list_find(colocated_rscs, rsc)) {
        return colocated_rscs;
    }

    crm_trace("%s: %s is supposed to be colocated with %s", orig_rsc->id, rsc->id, orig_rsc->id);
    colocated_rscs = g_list_append(colocated_rscs, rsc);

    for (gIter = rsc->rsc_cons; gIter != NULL; gIter = gIter->next) {
        rsc_colocation_t *constraint = (rsc_colocation_t *) gIter->data;
        resource_t *rsc_rh = constraint->rsc_rh;

        /* Break colocation loop */
        if (rsc_rh == orig_rsc) {
            continue;
        }

        if (constraint->score == INFINITY
            && filter_colocation_constraint(rsc, rsc_rh, constraint, TRUE) == influence_rsc_location) {

            if (rsc_rh->variant == pe_group) {
                /* Need to use group_variant_data */
                colocated_rscs = group_find_colocated_rscs(colocated_rscs, rsc_rh, orig_rsc);

            } else {
                colocated_rscs = find_colocated_rscs(colocated_rscs, rsc_rh, orig_rsc);
            }
        }
    }

    for (gIter = rsc->rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
        rsc_colocation_t *constraint = (rsc_colocation_t *) gIter->data;
        resource_t *rsc_lh = constraint->rsc_lh;

        /* Break colocation loop */
        if (rsc_lh == orig_rsc) {
            continue;
        }

        if (pe_rsc_is_clone(rsc_lh) == FALSE && pe_rsc_is_clone(rsc)) {
            /* We do not know if rsc_lh will be colocated with orig_rsc in this case */
            continue;
        }

        if (constraint->score == INFINITY
            && filter_colocation_constraint(rsc_lh, rsc, constraint, TRUE) == influence_rsc_location) {

            if (rsc_lh->variant == pe_group) {
                /* Need to use group_variant_data */
                colocated_rscs = group_find_colocated_rscs(colocated_rscs, rsc_lh, orig_rsc);

            } else {
                colocated_rscs = find_colocated_rscs(colocated_rscs, rsc_lh, orig_rsc);
            }
        }
    }

    return colocated_rscs;
}

void
process_utilization(resource_t * rsc, node_t ** prefer, pe_working_set_t * data_set)
{
    CRM_CHECK(rsc && prefer && data_set, return);
    if (safe_str_neq(data_set->placement_strategy, "default")) {
        GHashTableIter iter;
        GListPtr colocated_rscs = NULL;
        gboolean any_capable = FALSE;
        node_t *node = NULL;

        colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, rsc);
        if (colocated_rscs) {
            GHashTable *unallocated_utilization = NULL;
            char *rscs_id = crm_concat(rsc->id, "and its colocated resources", ' ');
            node_t *most_capable_node = NULL;

            unallocated_utilization = sum_unallocated_utilization(rsc, colocated_rscs);

            g_hash_table_iter_init(&iter, rsc->allowed_nodes);
            while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
                if (can_run_resources(node) == FALSE || node->weight < 0) {
                    continue;
                }

                if (have_enough_capacity(node, rscs_id, unallocated_utilization)) {
                    any_capable = TRUE;
                }

                if (most_capable_node == NULL ||
                    compare_capacity(node, most_capable_node) < 0) {
                    /* < 0 means 'node' is more capable */
                    most_capable_node = node;
                }
            }

            if (any_capable) {
                g_hash_table_iter_init(&iter, rsc->allowed_nodes);
                while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
                    if (can_run_resources(node) == FALSE || node->weight < 0) {
                        continue;
                    }

                    if (have_enough_capacity(node, rscs_id, unallocated_utilization) == FALSE) {
                        pe_rsc_debug(rsc,
                                     "Resource %s and its colocated resources"
                                     " cannot be allocated to node %s: not enough capacity",
                                     rsc->id, node->details->uname);
                        resource_location(rsc, node, -INFINITY, "__limit_utilization__", data_set);
                    }
                }

            } else if (*prefer == NULL) {
                *prefer = most_capable_node;
            }

            if (unallocated_utilization) {
                g_hash_table_destroy(unallocated_utilization);
            }

            g_list_free(colocated_rscs);
            free(rscs_id);
        }

        if (any_capable == FALSE) {
            g_hash_table_iter_init(&iter, rsc->allowed_nodes);
            while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
                if (can_run_resources(node) == FALSE || node->weight < 0) {
                    continue;
                }

                if (have_enough_capacity(node, rsc->id, rsc->utilization) == FALSE) {
                    pe_rsc_debug(rsc,
                                 "Resource %s cannot be allocated to node %s:"
                                 " not enough capacity",
                                 rsc->id, node->details->uname);
                    resource_location(rsc, node, -INFINITY, "__limit_utilization__", data_set);
                }
            }
        }
        pe__show_node_weights(true, rsc, "Post-utilization", rsc->allowed_nodes);
    }
}

#define VARIANT_GROUP 1
#include <lib/pengine/variant.h>

GListPtr
group_find_colocated_rscs(GListPtr colocated_rscs, resource_t * rsc, resource_t * orig_rsc)
{
    group_variant_data_t *group_data = NULL;

    get_group_variant_data(group_data, rsc);
    if (group_data->colocated || pe_rsc_is_clone(rsc->parent)) {
        GListPtr gIter = rsc->children;

        for (; gIter != NULL; gIter = gIter->next) {
            resource_t *child_rsc = (resource_t *) gIter->data;

            colocated_rscs = find_colocated_rscs(colocated_rscs, child_rsc, orig_rsc);
        }

    } else {
        if (group_data->first_child) {
            colocated_rscs = find_colocated_rscs(colocated_rscs, group_data->first_child, orig_rsc);
        }
    }

    colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, orig_rsc);

    return colocated_rscs;
}

static void
group_add_unallocated_utilization(GHashTable * all_utilization, resource_t * rsc,
                                  GListPtr all_rscs)
{
    group_variant_data_t *group_data = NULL;

    get_group_variant_data(group_data, rsc);
    if (group_data->colocated || pe_rsc_is_clone(rsc->parent)) {
        GListPtr gIter = rsc->children;

        for (; gIter != NULL; gIter = gIter->next) {
            resource_t *child_rsc = (resource_t *) gIter->data;

            if (is_set(child_rsc->flags, pe_rsc_provisional) &&
                g_list_find(all_rscs, child_rsc) == FALSE) {
                native_add_unallocated_utilization(all_utilization, child_rsc);
            }
        }

    } else {
        if (group_data->first_child &&
            is_set(group_data->first_child->flags, pe_rsc_provisional) &&
            g_list_find(all_rscs, group_data->first_child) == FALSE) {
            native_add_unallocated_utilization(all_utilization, group_data->first_child);
        }
    }
}


