/*
rsn.c
Copyright (c) 2010 Jacob Abel

Derived from Audacious's m3u.c
Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill,
		   Giacomo Lozito, Derek Pomery, and Yoshiki Yazawa.

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, see <http://www.gnu.org/licenses/>.
*/

#define BUFSIZE 256

#include <stdlib.h>		/* for system() */
#include <stdio.h>		/* for sprintf() */
#include <string.h>		/* for strlen(), memcpy(), and strcat() */
#include <glib.h>		/* for g types and g_ functions */
#include <audacious/plugin.h>	/* for Audacious macros, definitions, and aud_ functions
				   index_new() and index_append() are from libaudcore/index.h */
#include <audacious/playlist.h>
#include <audacious/misc.h>
#include <audacious/debug.h>

/* main function */
static void playlist_load_rsn(const gchar *filename, gint pos)
{
	/* to prevent a buffer overflow when using sprintf(), also to avoid using C99
	   subtract 7 from the filename because the 'file://' prefix isn't used */
	const gchar *unrarstr = "unrar e -ad -o+ -ep -y \"%s\" \"*.spc\" /tmp/";
	gsize i = strlen(filename);
	if ((i - 7) > (BUFSIZE - strlen(unrarstr) + 1))
		return;

	/* variable declarations/definitions */
	GDir *dir = NULL;
	struct index *add = NULL;
	gchar unrarcmd[BUFSIZE],
	      destdir[BUFSIZE] = "/tmp/",
	      spcfile[BUFSIZE],
	      *uri = NULL;
	const gchar *spcname = NULL;
	gsize j = i - 4, /* position of the dot preceding the "rsn" suffix */
	      k = strlen(destdir);

	/* extract .spc files to the /tmp/ folder using unrar
	   the non-free version of unrar is required because .rsn files are RARv3
	   the -ad switch tells unrar to "Append archive name to destination path"
	   add 7 to the filename to bypass the 'file://' prefix */
	sprintf(unrarcmd, unrarstr, filename + 7);
	if(system(unrarcmd))
		return;

	/* take filename without path or suffix and add to destdir, resulting in '/tmp/<filename>/' */
	while (filename[--i] != '/');
	while (++i < j) destdir[k++] = filename[i];
	destdir[k++] = '/'; destdir[k] = '\0';

	/* open destdir directory and add each extracted .spc file to new index */
	dir = g_dir_open(destdir, 0, NULL);
	add = index_new();
	while (((spcname = g_dir_read_name(dir)) != NULL) && (strstr (spcname, ".spc") == spcname + strlen (spcname) - 4))
	{
		memcpy(spcfile, destdir, BUFSIZE);
		strcat(spcfile, spcname);
		uri = aud_construct_uri(spcfile, filename);
		AUDDBG("uri=%s\n", uri);
		if (uri != NULL)
			index_append(add, uri);
	}
	g_dir_close(dir);

	aud_playlist_entry_insert_batch(aud_playlist_get_active(), pos, add, NULL);

	return;
}

static void playlist_save_rsn(const gchar *filename, gint pos)
{
	return;
}

PlaylistContainer plc_rsn = {
	.name = "RARed SPC Format",
	.ext = "rsn",
	.plc_read = playlist_load_rsn,
	.plc_write = playlist_save_rsn,
};

static void init(void)
{
	aud_playlist_container_register(&plc_rsn);
}

static void cleanup(void)
{
	aud_playlist_container_unregister(&plc_rsn);
}

DECLARE_PLUGIN(rsn, init, cleanup, NULL, NULL, NULL, NULL, NULL, NULL)

