#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <glib.h>

#include "../../include/fio.h"
#include "../../include/disk.h"
#include "../lib/endeavour2.h"

#include "downloadcfgio.h"
#include "config.h"

#define DOWNLOAD_LAST_FILE	"download_last.ini"


static gchar *DownloadCFGLastFile(edv_context_struct *ctx);

gint DownloadCFGGetLast(
	edv_context_struct *ctx,
	gchar **source_url,
	gchar **destination_path,
	gint *status	/* Return value of DownloadMonitor() */
);
void DownloadCFGSetLast(
	edv_context_struct *ctx,
	const gchar *source_url,
	const gchar *destination_path,
	gint status	/* Return value of DownloadMonitor() */
);


#define ATOI(s)         (((s) != NULL) ? atoi(s) : 0)
#define ATOL(s)         (((s) != NULL) ? atol(s) : 0)
#define ATOF(s)         (((s) != NULL) ? atof(s) : 0.0f)
#define STRDUP(s)       (((s) != NULL) ? g_strdup(s) : NULL)

#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
#define STRLEN(s)       (((s) != NULL) ? strlen(s) : 0)
#define STRISEMPTY(s)   (((s) != NULL) ? (*(s) == '\0') : TRUE)


/*
 *	Returns a dynamically allocated string specifying the path to
 *	the DOWNLOAD_LAST_FILE configuration file.
 */
static gchar *DownloadCFGLastFile(edv_context_struct *ctx)
{
	const gchar *cstrptr;

	if(ctx == NULL)
	    return(NULL);

	cstrptr = EDVGetS(ctx, EDV_CFG_PARM_DIR_LOCAL);
	if(cstrptr == NULL)
	    return(NULL);

	return(g_strdup_printf(
	    "%s%c%s", cstrptr, DIR_DELIMINATOR, DOWNLOAD_LAST_FILE
	));
}


/*
 *	Reads the download last configuration file and returns
 *	dynamically allocated paths specifying the last downloaded
 *	souce url and destination path.
 *
 *	Returns 0 on success or -1 on error.
 */
gint DownloadCFGGetLast(
	edv_context_struct *ctx,
	gchar **source_url,
	gchar **destination_path,
	gint *status	/* Return value of DownloadMonitor() */
)
{
	gchar *parm;
	gchar *cfg_file;
	FILE *fp;


	if(source_url != NULL)
	{
	    g_free(*source_url);
	    *source_url = NULL;
	}
	if(destination_path != NULL)
	{
	    g_free(*destination_path);
	    *destination_path = NULL;
	}
	if(status != NULL)
	    *status = -1;

	if(ctx == NULL)
	    return(-1);

	/* Get download last configuration file path */
	cfg_file = DownloadCFGLastFile(ctx);
	if(cfg_file == NULL)
	    return(-1);

	/* Open download last configuration file for reading */
	fp = FOpen(cfg_file, "rb");
	if(fp == NULL)
	{
	    g_free(cfg_file);
	    return(-1);
	}

	/* Begin reading last configuration file */
	parm = NULL;
	while(1)
	{
	    /* Get parameter of the next non-comment line */
	    parm = FSeekNextParm(
		fp, parm,
		EDV_CFG_COMMENT_CHAR, EDV_CFG_DELIMINATOR_CHAR
	    );
	    if(parm == NULL)
		break;

	    /* Check which parameter this line specifies */

	    if(!strcasecmp(parm, "LastSourceURL") &&
	       (source_url != NULL)
	    )
	    {
		g_free(*source_url);
		*source_url = FGetString(fp);
	    }
	    else if(!strcasecmp(parm, "LastDestinationPath") &&
		    (destination_path != NULL)
	    )
	    {
		g_free(*destination_path);
		*destination_path = FGetString(fp);
	    }
	    else if(!strcasecmp(parm, "LastStatus") &&
		    (status != NULL)
	    )
	    {
		gint vi[1];
		FGetValuesI(fp, vi, 1);
		*status = vi[0];
	    }
	    else
	    {
		FSeekNextLine(fp);
	    }
	}

	/* Close download last configuration file */
	FClose(fp);
	g_free(cfg_file);

	return(
	    ((*source_url != NULL) &&
	     (*destination_path != NULL)
	    ) ? 0 : -1
	);
}

/*
 *	Writes the download last configuration file, specifying the
 *	given information of the last downloaded object.
 */
void DownloadCFGSetLast(
	edv_context_struct *ctx,
	const gchar *source_url,
	const gchar *destination_path,
	gint status	/* Return value of DownloadMonitor() */
)
{
	gboolean file_existed;
	gchar *cfg_file;
	FILE *fp;


	if((ctx == NULL) || (source_url == NULL) || (destination_path == NULL))
	    return;

	/* Get download last configuration file path */
	cfg_file = DownloadCFGLastFile(ctx);
	if(cfg_file == NULL)
	    return;

	file_existed = access(cfg_file, F_OK) ? FALSE : TRUE;

	/* Open download last configuration file for writing */
	fp = FOpen(cfg_file, "wb");
	if(fp == NULL)
	{
	    g_free(cfg_file);
	    return;
	}

	/* Begin writing download last configuration file */
	fprintf(
	    fp,
"# Download Front End - Last Downloaded Object\n\
#\n\
# This file records the last downloaded object, it is used for\n\
# storing information in order to (re)download the last object.\n\
#\n"
	);
	if(source_url != NULL)
	    fprintf(
		fp, "LastSourceURL = %s\n", source_url
	    );
	if(destination_path != NULL)
	    fprintf(
		fp, "LastDestinationPath = %s\n", destination_path
	    );
	fprintf(
	    fp, "LastStatus = %i\n", status
	);

	/* Close download last configuration file */
	FClose(fp);
	if(file_existed)
	    EDVNotifyQueueObjectModified(ctx, cfg_file, NULL);
	else
	    EDVNotifyQueueObjectAdded(ctx, cfg_file);
	g_free(cfg_file);
}
