/*
 * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
 *
 * 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 <sys/stat.h>
#include <sys/param.h>

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

#include <glib.h>

#include <crm/pengine/status.h>
#include <pengine.h>
#include <allocate.h>
#include <utils.h>
#include <crm/common/ipcs.h>

xmlNode *do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now);

gboolean show_scores = FALSE;
gboolean show_utilization = FALSE;
int utilization_log_level = LOG_DEBUG_2;
extern int transition_id;

static pe_working_set_t *sched_data_set = NULL;

#define get_series() 	was_processing_error?1:was_processing_warning?2:3

typedef struct series_s {
    const char *name;
    const char *param;
    int wrap;
} series_t;

series_t series[] = {
    {"pe-unknown", "_dont_match_anything_", -1},
    {"pe-error", "pe-error-series-max", -1},
    {"pe-warn", "pe-warn-series-max", 200},
    {"pe-input", "pe-input-series-max", 400},
};

gboolean process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender);

gboolean
process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender)
{
    static char *last_digest = NULL;
    static char *filename = NULL;

    time_t execution_date = time(NULL);
    const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
    const char *op = crm_element_value(msg, F_CRM_TASK);
    const char *ref = crm_element_value(msg, F_CRM_REFERENCE);

    crm_trace("Processing %s op (ref=%s)...", op, ref);

    if (op == NULL) {
        /* error */

    } else if (strcasecmp(op, CRM_OP_HELLO) == 0) {
        /* ignore */

    } else if (safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) {
        /* ignore */

    } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) {
        crm_trace("Bad sys-to %s", crm_str(sys_to));
        return FALSE;

    } else if (strcasecmp(op, CRM_OP_PECALC) == 0) {
        int seq = -1;
        int series_id = 0;
        int series_wrap = 0;
        char *digest = NULL;
        const char *value = NULL;
        xmlNode *converted = NULL;
        xmlNode *reply = NULL;
        gboolean is_repoke = FALSE;
        gboolean process = TRUE;

        crm_config_error = FALSE;
        crm_config_warning = FALSE;

        was_processing_error = FALSE;
        was_processing_warning = FALSE;

        if (sched_data_set == NULL) {
            sched_data_set = pe_new_working_set();
            CRM_ASSERT(sched_data_set != NULL);
            set_bit(sched_data_set->flags, pe_flag_no_counts);
            set_bit(sched_data_set->flags, pe_flag_no_compat);
        }

        digest = calculate_xml_versioned_digest(xml_data, FALSE, FALSE, CRM_FEATURE_SET);
        converted = copy_xml(xml_data);
        if (cli_config_update(&converted, NULL, TRUE) == FALSE) {
            sched_data_set->graph = create_xml_node(NULL, XML_TAG_GRAPH);
            crm_xml_add_int(sched_data_set->graph, "transition_id", 0);
            crm_xml_add_int(sched_data_set->graph, "cluster-delay", 0);
            process = FALSE;
            free(digest);

        } else if (safe_str_eq(digest, last_digest)) {
            crm_info("Input has not changed since last time, not saving to disk");
            is_repoke = TRUE;
            free(digest);

        } else {
            free(last_digest);
            last_digest = digest;
        }

        if (process) {
            do_calculations(sched_data_set, converted, NULL);
        }

        series_id = get_series();
        series_wrap = series[series_id].wrap;
        value = pe_pref(sched_data_set->config_hash, series[series_id].param);

        if (value != NULL) {
            series_wrap = crm_int_helper(value, NULL);
            if (errno != 0) {
                series_wrap = series[series_id].wrap;
            }

        } else {
            crm_config_warn("No value specified for cluster"
                            " preference: %s", series[series_id].param);
        }

        seq = get_last_sequence(PE_STATE_DIR, series[series_id].name);
        crm_trace("Series %s: wrap=%d, seq=%d, pref=%s",
                  series[series_id].name, series_wrap, seq, value);

        sched_data_set->input = NULL;
        reply = create_reply(msg, sched_data_set->graph);
        CRM_ASSERT(reply != NULL);

        if (is_repoke == FALSE) {
            free(filename);
            filename =
                generate_series_filename(PE_STATE_DIR, series[series_id].name, seq, HAVE_BZLIB_H);
        }

        crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename);
        crm_xml_add_int(reply, "graph-errors", was_processing_error);
        crm_xml_add_int(reply, "graph-warnings", was_processing_warning);
        crm_xml_add_int(reply, "config-errors", crm_config_error);
        crm_xml_add_int(reply, "config-warnings", crm_config_warning);

        if (crm_ipcs_send(sender, 0, reply, crm_ipc_server_event) == FALSE) {
            int graph_file_fd = 0;
            char *graph_file = NULL;
            umask(S_IWGRP | S_IWOTH | S_IROTH);

            graph_file = crm_strdup_printf("%s/pengine.graph.XXXXXX",
                                           PE_STATE_DIR);
            graph_file_fd = mkstemp(graph_file);

            crm_err("Couldn't send transition graph to peer, writing to %s instead",
                    graph_file);

            crm_xml_add(reply, F_CRM_TGRAPH, graph_file);
            write_xml_fd(sched_data_set->graph, graph_file, graph_file_fd, FALSE);

            free(graph_file);
            free_xml(first_named_child(reply, F_CRM_DATA));
            CRM_ASSERT(crm_ipcs_send(sender, 0, reply, crm_ipc_server_event));
        }

        free_xml(reply);
        pe_reset_working_set(sched_data_set);

        if (was_processing_error) {
            crm_err("Calculated transition %d (with errors), saving inputs in %s",
                    transition_id, filename);

        } else if (was_processing_warning) {
            crm_warn("Calculated transition %d (with warnings), saving inputs in %s",
                     transition_id, filename);

        } else {
            crm_notice("Calculated transition %d, saving inputs in %s",
                       transition_id, filename);
        }

        if (crm_config_error) {
            crm_notice("Configuration ERRORs found during PE processing."
                       "  Please run \"crm_verify -L\" to identify issues.");
        }

        if (is_repoke == FALSE && series_wrap != 0) {
            unlink(filename);
            crm_xml_add_int(xml_data, "execution-date", execution_date);
            write_xml_file(xml_data, filename, HAVE_BZLIB_H);
            write_last_sequence(PE_STATE_DIR, series[series_id].name, seq + 1, series_wrap);
        } else {
            crm_trace("Not writing out %s: %d & %d", filename, is_repoke, series_wrap);
        }

        free_xml(converted);
    }

    return TRUE;
}

// only needed if process_pe_message() is called
void
libpengine_fini()
{
    pe_free_working_set(sched_data_set);
    sched_data_set = NULL;
}

xmlNode *
do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, crm_time_t * now)
{
    GListPtr gIter = NULL;
    int rsc_log_level = LOG_INFO;

/*	pe_debug_on(); */

    CRM_ASSERT(xml_input || is_set(data_set->flags, pe_flag_have_status));

    if (is_set(data_set->flags, pe_flag_have_status) == FALSE) {
        set_working_set_defaults(data_set);
        data_set->input = xml_input;
        data_set->now = now;

    } else {
        crm_trace("Already have status - reusing");
    }

    if (data_set->now == NULL) {
        data_set->now = crm_time_new(NULL);
    }

    crm_trace("Calculate cluster status");
    stage0(data_set);

    if(is_not_set(data_set->flags, pe_flag_quick_location)) {
        gIter = data_set->resources;
        for (; gIter != NULL; gIter = gIter->next) {
            resource_t *rsc = (resource_t *) gIter->data;

            if (is_set(rsc->flags, pe_rsc_orphan) && rsc->role == RSC_ROLE_STOPPED) {
                continue;
            }
            rsc->fns->print(rsc, NULL, pe_print_log, &rsc_log_level);
        }
    }

    crm_trace("Applying placement constraints");
    stage2(data_set);

    if(is_set(data_set->flags, pe_flag_quick_location)){
        return NULL;
    }

    crm_trace("Create internal constraints");
    stage3(data_set);

    crm_trace("Check actions");
    stage4(data_set);

    crm_trace("Allocate resources");
    stage5(data_set);

    crm_trace("Processing fencing and shutdown cases");
    stage6(data_set);

    crm_trace("Applying ordering constraints");
    stage7(data_set);

    crm_trace("Create transition graph");
    stage8(data_set);

    crm_trace("=#=#=#=#= Summary =#=#=#=#=");
    crm_trace("\t========= Set %d (Un-runnable) =========", -1);
    if (get_crm_log_level() >= LOG_TRACE) {
        gIter = data_set->actions;
        for (; gIter != NULL; gIter = gIter->next) {
            action_t *action = (action_t *) gIter->data;

            if (is_set(action->flags, pe_action_optional) == FALSE
                && is_set(action->flags, pe_action_runnable) == FALSE
                && is_set(action->flags, pe_action_pseudo) == FALSE) {
                log_action(LOG_TRACE, "\t", action, TRUE);
            }
        }
    }

    return data_set->graph;
}
