/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program 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 Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "config.h"

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif 

#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif 

#include "monit.h"
#include "socket.h"
#include "event.h"


/**
 *  Connect to a data collector servlet and send the event or status message.
 *
 *  @file
 */


/* ----------------------------------------------------------------- Private */


/**
 * Send message to the server
 * @param C An mmonit object
 * @param D Data to send
 * @return TRUE if the message sending succeeded otherwise FALSE
 */
static int data_send(Socket_T socket, Mmonit_T C, const char *D) {
        char *auth = Util_getBasicAuthHeader(C->url->user, C->url->password);
        int rv = socket_print(socket,
                          "POST %s HTTP/1.1\r\n"
                          "Host: %s:%d\r\n"
                          "Content-Type: text/xml\r\n"
                          "Content-Length: %d\r\n"
                          "Pragma: no-cache\r\n"
                          "Accept: */*\r\n"
                          "User-Agent: %s/%s\r\n"
                          "Connection: close\r\n"
                          "%s"
                          "\r\n"
                          "%s",
                          C->url->path,
                          C->url->hostname, C->url->port,
                          strlen(D),
                          prog, VERSION,
                          auth?auth:"",
                          D);
        FREE(auth);
        if (rv <0) {
                LogError("M/Monit: error sending data to %s -- %s\n", C->url->url, STRERROR);
                return FALSE;
        }
        return TRUE;
}


/**
 * Check that the server returns a valid HTTP response
 * @param C An mmonit object
 * @return TRUE if the response is valid otherwise FALSE
 */
static int data_check(Socket_T socket, Mmonit_T C) {
        int  status;
        char buf[STRLEN];
        
        if (! socket_readln(socket, buf, sizeof(buf))) {
                LogError("M/Monit: error receiving data from %s -- %s\n", C->url->url, STRERROR);
                return FALSE;
        }
        Str_chomp(buf);
        int n = sscanf(buf, "%*s %d", &status);
        if (n != 1 || (status >= 400)) {
                LogError("M/Monit: message sending failed to %s -- %s\n", C->url->url, buf);
                return FALSE;
        }
        return TRUE;
}


/* ------------------------------------------------------------------ Public */


/**
 * Post event or status data message to mmonit
 * @param E An event object or NULL for status data
 * @return If failed, return HANDLER_MMONIT flag or HANDLER_SUCCEEDED flag if succeeded
 */
int handle_mmonit(Event_T E) {
        int       rv = HANDLER_MMONIT;
        Socket_T  socket = NULL;
        Mmonit_T  C = Run.mmonits;
        
        /* The event is sent to mmonit just once - only in the case that the state changed */
        if (! C || (E && ! E->state_changed))
                return HANDLER_SUCCEEDED;
        
        StringBuffer_T sb = StringBuffer_create(256);
        for (; C; C = C->next) {
                if (! (socket = socket_create_t(C->url->hostname, C->url->port, SOCKET_TCP, C->ssl, C->timeout))) {
                        LogError("M/Monit: cannot open a connection to %s -- %s\n", C->url->url, STRERROR);
                        goto error;
                }
                status_xml(sb, E, E ? LEVEL_SUMMARY : LEVEL_FULL, 2, socket_get_local_host(socket));
                if (! data_send(socket, C, StringBuffer_toString(sb))) {
                        LogError("M/Monit: cannot send %s message to %s\n", E ? "event" : "status", C->url->url);
                        goto error;
                }
                StringBuffer_clear(sb);
                socket_shutdown_write(socket);
                if (! data_check(socket, C)) {
                        LogError("M/Monit: %s message to %s failed\n", E ? "event" : "status", C->url->url);
                        goto error;
                }
                rv = HANDLER_SUCCEEDED; // Return success if at least one M/Monit succeeded
                DEBUG("M/Monit: %s message sent to %s\n", E ? "event" : "status", C->url->url);
error:
                if (socket)
                        socket_free(&socket);
        }
        StringBuffer_free(&sb);
        return rv;
}

