/*
   album.c - Implements the Album API
   See README for Copyright and License
*/

#include "lfm_helper.h"
#include <string.h>

extern const char *LASTFM_IMAGE_SIZES[];

extern LASTFM_TAG_INFO *_new_LASTFM_TAG_INFO();

void LASTFM_free_album_info(LASTFM_ALBUM_INFO *a){
	if(!a)return;
	if(a->name)       free(a->name);
	if(a->artist)     free(a->artist);
	if(a->releasedate)free(a->releasedate);
	if(a->image)      free(a->image);
	if(a->image_url)  free(a->image_url);
	if(a->summary)    free(a->summary);
	free(a);
}

static void free_LASTFM_ALBUM_INFO(LASTFM_ALBUM_INFO *a, void *udata){
	LASTFM_free_album_info(a);
}

void LASTFM_free_album_info_list(LFMList *list){
	LFMList_foreach(list,(LFMFunc)free_LASTFM_ALBUM_INFO,NULL);
	LFMList_free(list);
}

void LASTFM_print_album_info(FILE *out, LASTFM_ALBUM_INFO *a){
	if(a == NULL) return;
	fprintf(out,"name        = %s\n",a->name);
	fprintf(out,"artist      = %s\n",a->artist);
	fprintf(out,"playcount   = %u\n",a->playcount);
	fprintf(out,"releasedate = %s\n",a->releasedate);
	fprintf(out,"image url   = %s\n",a->image_url);
	fprintf(out,"image size  = %zu\n",a->image_size);
	fprintf(out,"summary     = %s\n",a->summary);

	FILE *tmp = fopen("image.out","w+");
	fwrite(a->image,a->image_size,1,tmp);
	fclose(tmp);
}

LASTFM_ALBUM_INFO* _new_LASTFM_ALBUM_INFO(){
	LASTFM_ALBUM_INFO *a;
	a = malloc(sizeof(LASTFM_ALBUM_INFO));
	a->name        = NULL;
	a->artist      = NULL;
	a->releasedate = NULL;
	a->image       = NULL;
	a->image_size  = 0;
	a->playcount   = 0;
	a->summary     = NULL;
	a->image_url   = NULL;
	return a;
}

int LASTFM_album_get_top_tags(LASTFM_SESSION *s, const char *artist, const char *album,
								LFMList **result){
	XMLNode *xml=NULL, *xi, *xj;
	WebData *data = NULL;
	LASTFM_TAG_INFO *a = NULL;
	LFMList *out = NULL;
	char *buffer;
	char *q_album,*q_artist;
	int rv = LASTFM_STATUS_ERROR;

	if(s == NULL || strisspace(album) || strisspace(artist) ) 
		return LASTFM_STATUS_INVALID;
	
	q_album = curl_easy_escape(s->curl,album,0);
	q_artist = curl_easy_escape(s->curl,artist,0);

	buffer = malloc(LARGE_BUFFER);
	snprintf(buffer,LARGE_BUFFER,
		"%s?method=album.gettoptags&api_key=%s&album=%s&artist=%s&autocorrect=1",
		API_ROOT,s->api_key,q_album,q_artist);
	curl_free(q_album);
	curl_free(q_artist);
	
	data = lfm_helper_get_page(buffer,s);
	free(buffer);

	xml = tinycxml_parse(data->page);
	if(lfm_helper_get_status(s,xml))goto done;

	xi = xmlnode_get(xml, CCA { "lfm","toptags","tag",NULL },NULL,NULL);
	for(;xi;xi=xi->next){
		a = _new_LASTFM_TAG_INFO();
		LFMList_append(&out,a);

		xj = xmlnode_get(xi,CCA { "tag","name",NULL } ,NULL,NULL);
		if(xj && xj->content)
			a->name = unescape_HTML(strdup(xj->content));

		xj = xmlnode_get(xi,CCA {"tag","url",NULL},NULL,NULL);
		if(xj && xj->content)
			a->url = strdup(xj->content);
		
		xj = xmlnode_get(xi,CCA { "tag","count",NULL } ,NULL,NULL);
		if(xj && xj->content)
			a->count = atoi(xj->content);
	}

	rv = LASTFM_STATUS_OK;
	done:
	s->fraction = -1;
	xmlnode_free(xml);
	lfm_helper_free_page(data);
	*result = out;
	return rv;
}

int LASTFM_album_search(LASTFM_SESSION *s,const char *album, unsigned size, 
			unsigned limit, unsigned page, LFMList **results){

	XMLNode *xml=NULL, *xi, *xj;
	WebData *data = NULL,*image;
	LASTFM_ALBUM_INFO *a = NULL;
	LFMList *out = NULL, *li;
	char *buffer,*alb_tmp;
	unsigned download,img_size = 0;
	int rpages   = 0;
	int tpages   = 0;
	int tresults = 0;
	int cpage    = 0;
	int j;

	if(s == NULL || album == NULL) return -1;
	
	if(size >= LASTFM_IMAGE_URL_COUNT ){
		strcpy(s->status,"Invalid image size");
		return -1;
	}

	/* 30 is the maximum according to lastfm docs */
	if( (limit > 30) || (limit == 0) ) limit = 30;

	alb_tmp = curl_easy_escape(s->curl,album,0);

	buffer = malloc(LARGE_BUFFER);
	snprintf(buffer,LARGE_BUFFER,
		"%s?method=album.search&api_key=%s&album=%s&page=%u&limit=%u",
		API_ROOT,s->api_key,alb_tmp,page,limit);
	curl_free(alb_tmp);
	
	data = lfm_helper_get_page(buffer,s);
	free(buffer);

	xml = tinycxml_parse(data->page);
	if(lfm_helper_get_status(s,xml))goto done;

	xi = xmlnode_get(xml, CCA { "lfm","results","opensearch:totalResults",NULL },NULL,NULL);
	if(xi && xi->content)
		tresults = atoi(xi->content);
		
	if(tresults == 0) goto done;

	xi = xmlnode_get(xml, CCA { "lfm","results","opensearch:Query",NULL},"startPage",NULL);
	if(xi && xi->content)
		cpage = atoi(xi->content);

	/* round up the total_pages figure */
	tpages = (tresults/limit) + ((tresults % limit) != 0);
	rpages = tpages - cpage;

	if(size < LASTFM_IMAGE_COUNT){
		img_size = size;
		download = 1;
	}else if( size < LASTFM_IMAGE_URL_COUNT){
		img_size = size - LASTFM_IMAGE_URL_OG;
		download = 0;
	}
	
	xi = xmlnode_get(xml,CCA { "lfm","results","albummatches","album",NULL},NULL,NULL);
	for(;xi;xi=xi->next){
		a = _new_LASTFM_ALBUM_INFO();
		LFMList_append(&out,a);

		xj = xmlnode_get(xi,CCA { "album","name",NULL } ,NULL,NULL);
		if(xj && xj->content)
			a->name	= unescape_HTML(strdup(xj->content));

		xj = xmlnode_get(xi,CCA { "album","artist",NULL } ,NULL,NULL);
		if(xj && xj->content)
			a->artist = unescape_HTML(strdup(xj->content));

		for(j=img_size;LASTFM_IMAGE_SIZES[j];j++){
			xj = xmlnode_get(xi,CCA { "album","image",NULL } , "size",LASTFM_IMAGE_SIZES[j]);
			if(xj && xj->content) {
				a->image_url = strdup(xj->content);
				break;
			}
		}
	}

	/* If the user asks for 30 results, each image 60kb, 
	 * this could download 1.8mb! */
	if(download){
		for(li=out;li;li=li->next){
			a = li->data;
			image = lfm_helper_get_page(a->image_url,s);
			/* Sanity test */
			if(image && image->size > 1024){
				a->image  = malloc(image->size);
				memcpy(a->image,image->page,image->size);
				a->image_size = image->size;
			}
			lfm_helper_free_page(image);
		}
	}

	done:
	s->fraction = -1;
	xmlnode_free(xml);
	lfm_helper_free_page(data);
	*results = out;
	return rpages;
}

LASTFM_ALBUM_INFO *LASTFM_album_get_info(LASTFM_SESSION *s,
			const char *artist, const char *album){
	XMLNode *xml=NULL, *xi,*xj;
	LASTFM_ALBUM_INFO *a = NULL;
	WebData *data = NULL;
	WebData *image;
	char *art_tmp,*alb_tmp;
	char *buffer;
	int i;
  
	if(s == NULL) return NULL;

	if( !(artist && album) ){
		sprintf(s->status,"Artist and Album fields are mandatory");
		return NULL;
	}

	art_tmp = curl_easy_escape(s->curl,artist,0);
	alb_tmp = curl_easy_escape(s->curl,album,0);

	buffer = malloc(LARGE_BUFFER);
	snprintf(buffer,LARGE_BUFFER,
		"%s?method=album.getinfo&api_key=%s&artist=%s&album=%s&autocorrect=1",
			API_ROOT,s->api_key,art_tmp,alb_tmp);
	
	curl_free(art_tmp);
	curl_free(alb_tmp);

	data = lfm_helper_get_page(buffer,s);
	free(buffer);

	xml = tinycxml_parse(data->page);
	if(lfm_helper_get_status(s,xml))goto done;

	a = _new_LASTFM_ALBUM_INFO();

	xi = xmlnode_get(xml,CCA { "lfm","album",NULL } ,NULL,NULL);

	xj = xmlnode_get(xi,CCA {"album","name",NULL}, NULL,NULL);
	if(xj && xj->content)
		a->name = unescape_HTML(strdup(xj->content));

	xj = xmlnode_get(xi,CCA {"album","artist",NULL}, NULL,NULL);
	if(xj && xj->content)
		a->artist = unescape_HTML(strdup(xj->content));
	
	for(i=0;LASTFM_IMAGE_SIZES[i];i++){
		xj = xmlnode_get(xi,CCA { "album","image",NULL } , "size",LASTFM_IMAGE_SIZES[i]);
		if(xj && xj->content) {
			a->image_url = strdup(xj->content);
			break;
		}
	}

	xj = xmlnode_get(xi,CCA {"album","playcount",NULL},NULL,NULL);
	if(xj && xj->content)
		a->playcount = atoi(xj->content);

	if(a->image_url){
		/* Get Image */
		image = lfm_helper_get_page(a->image_url,s);
		if(image && image->size > 1024){
			a->image  = malloc(image->size);
			memcpy(a->image,image->page,image->size);
			a->image_size = image->size;
		}
		lfm_helper_free_page(image);
	}
		
	/* Get release date */
	xj = xmlnode_get(xi,CCA { "album","releasedate",NULL } ,NULL,NULL);
	if(xj && xj->content)
		a->releasedate = strdup(xj->content);

	/* Get Summary */
	xj = xmlnode_get(xi,CCA { "album","wiki","summary", NULL } ,NULL,NULL);
	if(xj && xj->content){
		a->summary = strdup(xj->content);
		unescape_HTML(a->summary);
	}

	done:
	s->fraction = -1;
	lfm_helper_free_page(data);
	xmlnode_free(xml);
	return a;
}
