/***************************************************************************
              downloads_attrib.c  -  downloads attributes stuff
             ---------------------------------------------------

                  - manages attribute data for downloads
                  - save attributes data to file
                  - read attributes data from file

    begin                : Wed Jul 10 2002
    copyright            : (C) 2002, 2003 by Tim-Philipp Müller
    email                : t.i.m@orange.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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "downloads_attrib.h"
#include "global.h"
#include "options.h"
#include "misc.h"
#include "status_page.h"

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <gtk/gtk.h>

static gboolean     loaded;             /* FALSE */
static GList       *attribute_records;  /* NULL  */


/* functions */

static void         downloadsattriblist_load (void);

static void         downloadsattriblist_save (void);


/***************************************************************************
 *
 *   downloadsattriblist_get_record
 *
 *   Returns the pointer to an existing attributes record.
 *    If none exists, one will be created.
 *
 *   Returns attribute record for this download.
 *
 ***************************************************************************/

GuiDownloadAttributes  *
downloadsattriblist_get_record (const guint8 *hash)
{
	GuiDownloadAttributes  *rec;
	GList                 *node;

	g_return_val_if_fail ( hash != NULL, NULL );

	if (!loaded)
	{
		loaded = TRUE;
		downloadsattriblist_load();
	}

	for ( node = attribute_records;  node != NULL;  node = node->next )
	{
		rec = (GuiDownloadAttributes*)node->data;

		if ((rec) && memcmp(rec->hash, hash, 16) == 0)
		{
			rec->last_used = time(NULL);
			return rec;
		}
	}

	rec = g_new0 (GuiDownloadAttributes, 1);

	memcpy(rec->hash, hash, 16);

	rec->time_added = time(NULL);
	rec->last_used  = time(NULL);

	attribute_records = g_list_append(attribute_records, rec);

	return rec;
}


/***************************************************************************
 *
 *   downloadsattriblist_save
 *
 *   Save downloads attributes list to file
 *
 ***************************************************************************/

static void
downloadsattriblist_save (void)
{
	const gchar  *fn;
	GList        *node;
	FILE         *f;

	fn = opt_get_opt_filename ("gui_downloadstats.txt");

	g_return_if_fail (fn != NULL);

	f = fopen (fn, "w");

	if ( f == NULL )
	{
		status_system_error_msg (_("Couldn't open gui_downloadsstats.txt for writing."));
		return;
	}

	fprintf (f, "# ed2k_gui --- gui_downloadsstats --- config format version 0.3.0\n");
	fprintf (f, "#\n%s\n", _("# This file is created by the ed2k gui. It contains information about your"));
	fprintf (f, "%s\n#\n", _("# downloads. DO NOT CHANGE THE ABOVE HEADER!"));
	fprintf (f, "%s\n#\n", _("# hash - last seen downloading - last seen fully available - last used - time added"));

	for ( node = attribute_records;  node != NULL;  node = node->next )
	{
		GuiDownloadAttributes *rec = (GuiDownloadAttributes*) node->data;

		/* Don't save records which haven't been used in more than 1 month */
		if ((rec) && (time(NULL) - rec->last_used) < 3600*24*31)
		{
			fprintf (f, "%32s %lu %lu %lu %lu\n",
				hash_to_hash_str(rec->hash),
				rec->last_downloading,
				rec->last_complete,
				rec->last_used,
				rec->time_added);
		}
	};

	fclose(f);

}


/***************************************************************************
 *
 *   everyFiveMinutes
 *
 ***************************************************************************/

static gboolean
everyFiveMinutes (gpointer data)
{
	downloadsattriblist_save();

	return TRUE; /* call again */
}


/***************************************************************************
 *
 *   downloadsattriblist_load
 *
 *   Loads the downloads attributes list from a file.
 *
 ***************************************************************************/

static void
downloadsattriblist_load (void)
{
	const gchar    *fn;
	gchar         **line, **linearray;
	guint           vermaj, vermin, verminmin;
	gint            ret;

	g_atexit(&downloadsattriblist_save);
	g_timeout_add(5*60*1000, (GSourceFunc) everyFiveMinutes, NULL);

	fn = opt_get_opt_filename("gui_downloadstats.txt");

	g_return_if_fail ( fn != NULL );

	linearray = misc_get_array_of_lines_from_textfile (fn, FALSE, TRUE);

	if (!linearray)
		return;

	line = linearray;
	ret = sscanf(*line, "# ed2k_gui --- gui_downloadsstats --- config format version %u.%u.%u\n", &vermaj, &vermin, &verminmin);
	if ( ret != 3)
	{
		g_printerr ("%s", _("gui_downloadsstats.txt: invalid header?\n"));
		g_strfreev (linearray);
		return;
	}

	for ( line++;  *line != NULL;  line++ )  /* skip header line; process line by line until end */
	{
		GuiDownloadAttributes *rec;
		guint8                hashstr[33];
		guint                 last_downloading;
		guint                 last_fullyavailable;
		guint                 last_used, time_added;

		if (**line =='#' || **line == 0x00) /* skip comments and empty lines */
			continue;

		ret = sscanf(*line, "%32s %u %u %u %u\n", hashstr, &last_downloading, &last_fullyavailable, &last_used, &time_added);

		if (ret != 5 )
			continue;

		rec = downloadsattriblist_get_record(hash_str_to_hash(hashstr));

		g_assert( rec != NULL );

		rec->last_downloading = (time_t) last_downloading;
		rec->last_complete    = (time_t) last_fullyavailable;
		rec->last_used        = (time_t) last_used;
		rec->time_added       = (time_t) time_added;
	}

	g_strfreev (linearray);
}


