/*  client_config.c  --  Handles reading and parsing of config files
 *
 *  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   client_config.c
 * @author David Sommerseth <dazo@users.sourceforge.net>
 * @date   2008-12-01
 *
 * @brief  Config file parser for eurephiadm
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <assert.h>

#include <eurephia_nullsafe.h>
#include <eurephia_values.h>
#include <eurephia_cfgfile.h>

/**
 * Retrieve a the full path of a file name.  Will try to look for the file in different places, like
 * if EUREPHIA_DIR is set, it will look here or else in ${HOME}/.eurephia.
 *
 * @param env   const char * to an environment variable to look for the given filename
 * @param file  File name which we are looking for
 *
 * @return Returns a full path to the file name, or NULL on error.
 */
char *get_config_filename(const char *env, const char *file) {
        struct stat chk;
        static char fname[1026];
        char *ptr;
        int flen = 1024 - strlen_nullsafe(file);

        assert( (file != NULL));
        memset(&fname, 0, 1026);

        if( env != NULL ) {
                // Use the explicit eurephia session file, if set in environment
                if( (ptr = getenv(env)) != NULL ) {
                        snprintf(fname, 1024, "%s", ptr);
                        return fname;
                }
        }

        // Use the explicit set eurephia session directory for a session file
        if( ((ptr = getenv("EUREPHIA_DIR")) != NULL) && (strlen_nullsafe(ptr) <= 1016) ) {
                strncat(fname, ptr, flen-1);
                strcat(fname, "/");
                strcat(fname, file);
                // Make sure we have this directory
                if( stat(ptr, &chk) == -1 ) {
                        if( mkdir(ptr, S_IRWXU) == -1 ) {
                                fprintf(stderr, "Could not create eurephia directory: %s\n", ptr);
                                return NULL;
                        }
                }
                return fname;
        }

        // Use default ~/.eurephia directory for session file
        if( ((ptr = getenv("HOME")) != NULL) && (strlen_nullsafe(ptr) <= 1016) ) {
                flen -= 10;
                strncat(fname, ptr, flen);
                strcat(fname, "/.eurephia");

                // Make sure we have this directory
                if( stat(fname, &chk) == -1 ) {
                        if( mkdir(fname, S_IRWXU) == -1 ) {
                                fprintf(stderr, "Could not create eurephia directory: %s\n", fname);
                                return NULL;
                        }
                }
                strcat(fname, "/");
                strcat(fname, file);
                return fname;
        }
        return NULL;
}


/**
 * Parses a complete config file and puts it into an eurephiaVALUES key/value stack
 *
 * @param env     Environment table, used for locating the config file
 * @param cfgname File name of the configuration file.
 *
 * @return Returns a pointer to an eurephiaVALUES stack containing the configuration on success,
 *         otherwise NULL.
 */
eurephiaVALUES *ReadConfig(const char *env, const char *cfgname) {
        char *fname = NULL;
        eurephiaVALUES *cfg = NULL;

        fname = get_config_filename(env, cfgname);
        if( fname == NULL ) {
                fprintf(stderr, "Could not find a valid path for the config file\n");
                return NULL;
        }

        cfg = ecfg_ReadConfig(NULL, fname);
        if( cfg == NULL ) {
                fprintf(stderr, "Failed to parse the config file (%s)\n", cfgname);
        }
        return cfg;
}
