/* edit_config.c  --  eurephiadm command:
 *                    Sets, deletes or prints a config setting in the database
 *
 *  GPLv2 only - Copyright (C) 2008 - 2012
 *               David Sommerseth <dazo@users.sourceforge.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; version 2
 *  of the License.
 *
 *  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 General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

/**
 * @file   eurephiadm/commands/edit_config.c
 * @author David Sommerseth <dazo@users.sourceforge.net>
 * @date   2008-12-02
 *
 * @brief  eurephia config command. Sets, deletes or retrieves config settings
 *
 */


#include <stdio.h>
#include <string.h>
#include <assert.h>

#include <libxml/tree.h>

#include <eurephia_nullsafe.h>
#include <eurephia_context.h>
#include <eurephia_log.h>
#include <eurephia_xml.h>
#include <eurephia_values_struct.h>
#include <eurephia_values.h>
#include <eurephiadb_session_struct.h>
#include <eurephiadb_driver.h>

#define MODULE "eurephiadm::config" /**< Need to define the active module before including argparser.h */
#include "../argparser.h"

/**
 * config help screen.
 *
 */
void help_EditConfig() {
        printf("%s - Edit eurephia configuration\n\n", MODULE);
        printf("  The config command let you add, change or delete\n"
               "  configuration parameters in the eurephia database\n"
               "  in an easy way.  To be allowed to do so, you must\n"
               "  have been granted 'config' access.\n\n");

        printf("  The following arguments are accepted:\n"
               "        -l | --list                   List all parameters in db\n"
               "        -s | --set <key> <value>      Add/change a parameter.\n"
               "        -D | --delete <key>           Remove the parameter.\n"
               "\n"
               "  If no arguments is given, you can give a key name, and the\n"
               "  associated value will be printed.\n\n"
               "        eurephiadm config <key>\n\n");

        printf("  The command will exit with exit code 0 on success.\n\n");
}

/**
 * Reusing this function for the --list argument
 */
int cmd_ShowCfg(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv);

/**
 * Main function for the config command.
 *
 * @param ctx   eurephiaCTX
 * @param sess  eurephiaSESSION of the current logged in user
 * @param cfg   eurephiaVALUES struct of the current configuration
 * @param argc  argument count for the eurephiadm command
 * @param argv  argument table for the eurephiadm command
 *
 * @return returns 0 on success, otherwise 1.
 */
int cmd_EditConfig(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) {
        int rc = 0, i = 0;
        xmlDoc *cfgxml = NULL, *resxml = NULL;
        xmlNode *cfg_n = NULL;

        e_options editargs[] = {
                {"--set", "-s", 2},
                {"--delete", "-D", 1},
                {"--list", "-l", 0},
                {"--help", "-h", 0},
                {NULL, NULL, 0}
        };

        assert((ctx != NULL) && (ctx->dbc != NULL) && (ctx->dbc->config != NULL));

        for( i = 1; i < argc; i++ ) {
                if( *argv[i] != '-' ) {
                        break;
                }
                switch( eurephia_getopt(&i, argc, argv, editargs) ) {
                case 's':
                        eurephiaXML_CreateDoc(ctx, 1, "configuration", &cfgxml, &cfg_n);
                        cfg_n = xmlNewChild(cfg_n, NULL, (xmlChar *) "set", (xmlChar *) optargs[1]);
                        xmlNewProp(cfg_n, (xmlChar *) "key", (xmlChar *) optargs[0]);
                        resxml = eDBadminConfiguration(ctx, cfgxml);
                        xmlFreeDoc(cfgxml);
                        break;

                case 'D':
                        eurephiaXML_CreateDoc(ctx, 1, "configuration", &cfgxml, &cfg_n);
                        cfg_n = xmlNewChild(cfg_n, NULL, (xmlChar *) "delete", NULL);
                        xmlNewProp(cfg_n, (xmlChar *) "key", (xmlChar *) optargs[0]);
                        resxml = eDBadminConfiguration(ctx, cfgxml);
                        xmlFreeDoc(cfgxml);
                        break;

                case 'l':
                        cmd_ShowCfg(ctx, NULL, NULL, 0, NULL);
                        return 0;

                case 'h':
                        help_EditConfig();
                        return 0;

                default:
                        return 1;
                }
        }

        if( argc == 2 ) {
                char *val = eGet_value(ctx->dbc->config, argv[1]);
                if( val ) {
                        fprintf(stdout, "%s\n", val);
                } else {
                        fprintf(stderr, "(%s is not set)\n", argv[1]);
                }
                rc = 1;
        } else if( argc == 1 ){
                fprintf(stderr, "No config action performed\n");
                rc = 1;
        } else if( resxml != NULL ) {
                eurephiaRESULT *res = NULL;

                res = eurephiaXML_ParseResultMsg(ctx, resxml);
                if( res == NULL ) {
                        fprintf(stderr, "%s: Error updating the configuration. No results returned.\n",
                                MODULE);
                        return rc = 1;
                }

                if( res->resultType == exmlERROR ) {
                        fprintf(stderr, "%s: %s\n", MODULE, res->message);
                        rc = 1;
                } else {
                        fprintf(stdout, "%s: %s\n", MODULE, res->message);
                        rc = 0;
                }
                xmlFreeDoc(resxml);
                free_nullsafe(ctx, res);
        }  else {
                fprintf(stderr, "Unexpected error while performing configuration changes\n");
                rc = 1;
        }
        return (rc != 1);
}
