/* GAdmin-Rsync - An easy to use GTK+ frontend for the rsync backup client and server.
 * Copyright (C) 2007-2011 Magnus Loef <magnus-swe@telia.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 3 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
*/



#include "../config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "gettext.h"
#include "widgets.h"
#include "show_info.h"
#include "allocate.h"
#include "create_rsync_tab.h"
#include "populate_rsync_tab.h"
#include "commands.h"
#include "commented.h"
#include "get_option_pos.h"
#include <dirent.h>

#define MAX_TIME_LINE 100

extern gchar *global_settings_dir;
extern gchar *global_backup_name;

/* Show info about missing paths once */
int path_err = 0;

extern gulong backup_combo_changed_signal;



/* Populates the backup selection combo and returns number of selections */
int populate_backup_combo(struct w *widgets)
{
    int i = 0, x = 0, count = 0;
    struct dirent **namelist;
    gchar *conf_file, *utf8=NULL;
    GtkTreeModel *model;

    /* Need to block the changed signal for this widget. See BigBug a few rows down. */
    g_signal_handler_block(GTK_WIDGET(widgets->rsync_set_combo[0]), backup_combo_changed_signal);

    /* Get selected backup name from the combo */
    global_backup_name = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widgets->rsync_set_combo[0]));

    /* Clear the "backup name" combo */
    model = gtk_combo_box_get_model(GTK_COMBO_BOX(widgets->rsync_set_combo[0]));

    /* This activates the changed signal in fedora 8/9 as of: 2008-06-06. Smells like BigBug. */
    gtk_list_store_clear(GTK_LIST_STORE(model));


    /* Read the settings dir */
    i = scandir(global_settings_dir, &namelist, 0, alphasort);
    if( i < 0 )
    {
	perror("scandir");
	return 0;
    }

    for(x=0; x<i; x++)
    {
	/* Skip the directory up/down dots */
	if( strcmp(namelist[x]->d_name, ".")  == 0
	||  strcmp(namelist[x]->d_name, "..") == 0 )
	{
	    free(namelist[x]);
	    continue;
	}
	
	/* Insert "backup names" into the backup selection combo */
	utf8 = g_locale_to_utf8(namelist[x]->d_name, strlen(namelist[x]->d_name), NULL, NULL, NULL);

	gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->rsync_set_combo[0]), utf8);
	
	/* If theres no selected "backup name", set this as selected in the combo */
	if( count == 0 && global_backup_name == NULL )
	{
	    count++;
	
	    gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->rsync_set_combo[0]), 0);

	    /* Save the path for treeview population */
	    conf_file = g_strdup_printf("%s/%s", global_settings_dir, namelist[x]->d_name);
	    global_backup_name = g_strdup_printf("%s", namelist[x]->d_name);
	}

	/* If theres a selected "backup name", set it as selected if found */
	if( global_backup_name!=NULL && strcmp(global_backup_name, namelist[x]->d_name) == 0 )
	{
	    gtk_combo_box_set_active(GTK_COMBO_BOX(widgets->rsync_set_combo[0]), x-2);

	    /* Save the path for treeview population */
	    conf_file = g_strdup_printf("%s/%s", global_settings_dir, namelist[x]->d_name);
	    global_backup_name = g_strdup_printf("%s", namelist[x]->d_name);
	}
	g_free(utf8);
	free(namelist[x]);
	
	count++;
    }
    free(namelist);

    /* Unblock the signal */
    g_signal_handler_unblock(GTK_WIDGET(widgets->rsync_set_combo[0]), backup_combo_changed_signal);

    return count;
}


/* Inserts rsync tab settings */
void populate_rsync_tab(struct w *widgets)
{
    FILE *fp;
    long opt_pos=0, conf_size=0;
    char *line, *opt, *new_buffer, *timebuf;
    gchar *conf_file = NULL, *utf8 = NULL;
    GtkTreeIter iter;
    int prev_newline=0, one_time=0, i=0, x=0;

    /* Clear the treeview */
    gtk_list_store_clear(GTK_LIST_STORE(widgets->backup_store));

    /* Deselect all toggle buttons */
    for(i=0; i<10; i++)
    {
	gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[i]), FALSE);
    }
    /* Set it to any month by default */
    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[1]), TRUE);

    /* Set backup at shutdown to off by default */
    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->backup_at_shutdown_check_button), FALSE);

    /* Populate the backup combo */
    if( populate_backup_combo(widgets) )
    {
        conf_file = g_strdup_printf("%s/%s", global_settings_dir, global_backup_name);
    }
    else /* No selections found. Create a new backup dialog. */
    {
        create_new_backup_window(widgets);
        if( conf_file!=NULL )
          g_free(conf_file);

        return;
    }

    /* Populate the backup treeview with this conf file */
    if((fp=fopen(conf_file, "r"))==NULL)
    {
	g_free(conf_file);
        return;
    }
    fseek(fp, 0, SEEK_END);
    conf_size = ftell(fp);
    rewind(fp);

    line = allocate(conf_size+1);
    new_buffer = allocate(conf_size+1);
    opt = allocate(16384+1);
    timebuf = allocate(MAX_TIME_LINE+1);

    if( conf_size > 1 )
    while(fgets(line, conf_size, fp)!=NULL)
    {                                 
	if( commented(line) )
	  continue;

	if( strlen(line) > 16384 )
	  continue;

	if( ! strstr(line,"schedule_") )
	{
	    /* Append a row once if the data length is valid */
	    if( ! one_time && strlen(line) > 3 )
	    {
		gtk_list_store_append(GTK_LIST_STORE(widgets->backup_store), &iter);
		one_time++;
	    }

	    /* Record newline */
	    if( line[0]=='\n' )
	    {
		prev_newline = 1;
		continue;
	    }
	
	    /* Append a row if the previous one was a newline and we have a valid data length */
	    if( prev_newline && strlen(line) > 3 )
	    {
		gtk_list_store_append(GTK_LIST_STORE(widgets->backup_store), &iter);
		prev_newline = 0;
	    }
	}
	
	/* Remove newline chars */
	opt_pos = get_option_pos(line);
	snprintf(opt, 16384, "%s", &line[opt_pos]);
	if( opt[strlen(opt)-1]=='\n' )
	  opt[strlen(opt)-1]='\0';

	/* Source server */
	if( strstr(line, "src_server") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 0, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Source path */
	if( strstr(line, "src_path") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 1, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Dest server */
	if( strstr(line, "dst_server") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 2, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Dest path */
	if( strstr(line, "dst_path") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 3, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Include files */
	if( strstr(line, "include_files") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 4, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Exclude files */
	if( strstr(line, "exclude_files") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 5, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Include value */
	if( strstr(line, "include_value") )
	{
	    if( strstr(line, "1") )
	      gtk_list_store_set(widgets->backup_store, &iter, 6, TRUE, -1);
	    else
	      gtk_list_store_set(widgets->backup_store, &iter, 6, FALSE, -1);
	}
	/* Delete destination files that does not exist in source value */
	if( strstr(line, "del_dst_files_value") )
	{
	    if( strstr(line, "1") )
	      gtk_list_store_set(widgets->backup_store, &iter, 7, TRUE, -1);
	    else
	      gtk_list_store_set(widgets->backup_store, &iter, 7, FALSE, -1);
	}

	/* Server user */
	if( strstr(line, "server_user") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 8, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Server port */
	if( strstr(line, "server_port") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 9, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}
	/* Private key path */
	if( strstr(line, "priv_key_path") )
	{
	    utf8 = g_locale_to_utf8(opt, strlen(opt), NULL, NULL, NULL);
	    gtk_list_store_set(widgets->backup_store, &iter, 10, utf8, -1);
	    if( utf8!=NULL )
	      g_free(utf8);
	}


	/* Is backup scheduled at shutdown... */
	if( strstr(line, "schedule_backup_at_computer_shutdown:") )
	{
	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->backup_at_shutdown_check_button), TRUE);
	}

	/* Is scheduling used... */
	if( strstr(line, "schedule_") )
	{
	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[0]), TRUE);
	}

	/* Schedule month day */
	if( strstr(line, "schedule_month_day") )
	{
	    timebuf[0]='\0';
	    x = 1; /* Default value */
	    
	    /* Get and insert the month day */
	    for(i=0; i<5 && opt[i]!='\0'; i++)
	    {
		timebuf[i] = opt[i];
	    }
	    if( timebuf[strlen(timebuf)-1]=='\n' )
	      timebuf[strlen(timebuf)-1]='\0';

	    x = atoi(timebuf);
	    gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->schedule_spin_button[0]), x);

	    /* Uncheck shedule every month day */
	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[1]), FALSE);
	}
	/* Schedule every month day is enabled */
	if( strstr(line, "schedule_every_month_day") )
	{
	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[1]), TRUE);
	}

	/* Schedule days */
	if( strstr(line, "schedule_days") )
	{
	    for(i=0; opt[i]!='\0'; i++)
	    {
		if( i < 9 )
		{
		    /* Checkbuttons are 2-8 */
		    if( opt[i]=='1' )
		      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[i+2]), TRUE);
		    else
		      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[i+2]), FALSE);
		}
	    }	    
	}
	/* Schedule time (hour, minute) */
	if( strstr(line, "schedule_time") )
	{
	    /* Contains hour or minute (12:30) */
	    timebuf[0]='\0';
	    x = 1; /* Default value */
	    
	    /* Get and insert the hour */
	    for(i=0; i<5 && opt[i]!=':' && opt[i]!='\0'; i++)
	    {
		timebuf[i] = opt[i];
	    }
	    if( timebuf[strlen(timebuf)-1]=='\n' )
	      timebuf[strlen(timebuf)-1]='\0';

	    x = atoi(timebuf);
	    gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->schedule_spin_button[1]), x);

	    /* Skip colon */
	    i++;

	    /* Clear the buffer */
	    memset(timebuf, '\0', sizeof(timebuf));

	    /* Get and insert the minute */
	    x = 0; /* Dont change the '0' */
	    for(i=i; i<5 && opt[i]!='\0'; i++)
	    {
		timebuf[x] = opt[i];
		x++;
	    }
	    if( timebuf[strlen(timebuf)-1]=='\n' )
	      timebuf[strlen(timebuf)-1]='\0';

	    x = atoi(timebuf);
	    gtk_spin_button_set_value(GTK_SPIN_BUTTON(widgets->schedule_spin_button[2]), x);
	}

	/* Schedule every hour is enabled */
	if( strstr(line, "schedule_every_hour") )
	{
	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[9]), TRUE);
	}
	/* Schedule every minute is enabled */
	if( strstr(line, "schedule_every_minute") )
	{
	    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widgets->schedule_check_button[10]), TRUE);
	}
    }
    fclose(fp);
    free(line);
    free(opt);
    free(timebuf);
    free(new_buffer);
    g_free(conf_file);
}
