/*************************************************************************************************************
* This file contains ftp download functions
* 2012/8 by Dlxko
* Version 3.0
**************************************************************************************************************/
#include "FTPDownload.h"

// Local statics
static  CURL *curl;
static GThread *thread;
static  CURLcode result;
static int buddy_number;
static int character_count;
static GtkTextIter end_iter;
static char file_name[FILE_NAME_SIZE];
static char remote_addres[FILE_PATH_SIZE];
static char message_number[MSG_NUMB_SIZE];

// File struct
struct thread_FtpFile
{
	const char *filename;
	FILE *stream;
};

// Function to save file datas
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
	// Ouput file from file struc
	struct thread_FtpFile *out = (struct thread_FtpFile *)stream;

	// Open file for writing
	if(out && !out->stream)
	{
		out->stream=fopen(file_name, "wb");

		// If error report
		if(!out->stream)
		{
			function_show_warning_ftp(LANG_XOPEN_FILE_FOR_DOWNLOAD, 2);
			return -1;
		}
	}
	return fwrite(buffer, size, nmemb, out->stream);
}

// Thread function
static gpointer thread_func( gpointer data )
{
	// Struct for saved file
	struct thread_FtpFile ftpfile =
	{
		file_name,
		NULL
	};

	// Init curl
	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();

	// Check if initialized
	if(!curl)
	{
		function_show_warning_ftp(LANG_XINITIALIZE_CURL_DOWNLOAD, 2);
		return (NULL);
	}

	// Set remote adress
	curl_easy_setopt(curl, CURLOPT_URL, remote_addres);
	// Define writing funcion
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
	// Set pointer to struc
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
	// Debug ouput
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
	// Perform script
	result = curl_easy_perform(curl);
	// Cleanup
	curl_easy_cleanup(curl);

	// Add mark of failed status
	if(CURLE_OK != result)
	{
		// Add mark of failed status
		gtk_text_buffer_get_iter_at_offset(buddy[buddy_number].buffer, &end_iter, character_count);
		gtk_text_buffer_insert_pixbuf(buddy[buddy_number].buffer, &end_iter, px_failed);
	}
	// If allright
	else
	{
		// Add mark of downloaded status
		gtk_text_buffer_get_iter_at_offset(buddy[buddy_number].buffer, &end_iter, character_count);
		gtk_text_buffer_insert_pixbuf(buddy[buddy_number].buffer, &end_iter, px_send);

		// Count lenght
		sending_text_len = LENGHT_SIZE+DATA_ONE_SIZE+OPCODE_SIZE+MSG_NUMB_SIZE;
		sprintf_s(sending_text_len_char, LENGHT_SIZE, "%d", sending_text_len);

		// Check packet integrity
		if((strlen(buddy[buddy_number].nick_name) > 0) && (strlen(message_number) > 0))
		{
			// Update text for server with "DX_OPCODE_SNT" and name datas
			memset(sending_text,0,BUF_SIZE);
			memcpy(sending_text, sending_text_len_char, LENGHT_SIZE);
			memcpy(&sending_text[LENGHT_SIZE], DX_OPCODE_SNT, OPCODE_SIZE);
			memcpy(&sending_text[LENGHT_SIZE+OPCODE_SIZE], buddy[buddy_number].nick_name, strlen(buddy[buddy_number].nick_name));
			memcpy(&sending_text[LENGHT_SIZE+OPCODE_SIZE+DATA_ONE_SIZE], message_number, strlen(message_number));

			// Send socket
			function_send_data(sending_text, sending_text_len);
		}
	}

	// Cleanup
	if(ftpfile.stream)
		fclose(ftpfile.stream);
	curl_global_cleanup();
	active_ftp_download = false;

	// Exit thread and return
	g_thread_exit( NULL );
	return ( NULL );
}

// Main function to initialize download
void function_ftp_download(char function_remote_addr[FILE_PATH_SIZE], char function_file_name[FILE_NAME_SIZE], int function_buddy_number, GtkTextIter function_end_iter, char function_msg_number[MSG_NUMB_SIZE])
{
	// Alloc error
	GError *error = NULL;

	// Activate download
	if(active_ftp_download == true)
	{
		function_show_warning(LANG_ONLY_ONE_FTP_DOWNLOAD_ALLOWED);
		return;
	}

	// Check function datas
	if((strlen(function_remote_addr) < 1) || (strlen(function_file_name) < 1) || (function_buddy_number == (MAX_BUDDIES + 1)))
	{
		function_show_warning_ftp(LANG_XGET_DATA_FOR_INIT_DOWNLOAD, 2);
		return;
	}

	// Activate ftp download
	active_ftp_download = true;

	// Save msg number
	memcpy(message_number, function_msg_number, MSG_NUMB_SIZE);

	// Save end iter
	end_iter = function_end_iter;

	// Store buddy number
	buddy_number = function_buddy_number;

	// Save remote adress
	strcpy_s(remote_addres, FILE_PATH_SIZE, function_remote_addr);

	// Save filename
	strcpy_s(file_name, FILE_NAME_SIZE, function_file_name);

	// Add mark of receiving
	gtk_text_buffer_get_end_iter(buddy[buddy_number].buffer, &end_iter);
	gtk_text_buffer_insert_pixbuf(buddy[buddy_number].buffer, &end_iter, px_receiving);
	character_count = gtk_text_buffer_get_char_count(buddy[buddy_number].buffer);

	// Create thread with parameters else return error
	thread = g_thread_create_full( thread_func, NULL, 0, FALSE, TRUE,  G_THREAD_PRIORITY_LOW, &error );
	if(!thread || error)
	{
		memset(dialog_text, 0, DIALOG_BUFFER_SIZE);
		sprintf(dialog_text, "%s : %s",LANG_XCREATE_DOWNLOAD_THREAD, error->message);
		function_show_warning_ftp(dialog_text, 2);
		g_error_free(error);
	}
}