import groovy.json.JsonSlurper;

import org.serviio.library.online.ContentURLContainer;
import org.serviio.library.online.PreferredQuality;
import org.serviio.library.online.WebResourceContainer;
import org.serviio.library.online.WebResourceItem;
import org.serviio.library.online.WebResourceUrlExtractor;
import org.serviio.library.metadata.MediaFileType;


class EightTracks extends WebResourceUrlExtractor {

	final static USER_AGENT		= 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1'
	final static MIX_INFO_REGEX	= /new TRAX.Mix\((.*?)\);/
	
	@Override
	protected WebResourceContainer extractItems(URL url, int maxItemsToRetrieve) {
		String pageSource = openURL(url, USER_AGENT)
		Map mixData = convertToJson((pageSource=~MIX_INFO_REGEX)[0][1])
		String thumbnailUrl = mixData.cover_urls.sq56
		
		List<WebResourceItem> items = []
		def firstSong = extractFirstSong( mixData.id, thumbnailUrl )
		items << firstSong
		
		int currentSongId = firstSong.additionalInfo.id
		int counter = 1;
		while(!firstSong.additionalInfo.at_last_track && true){
			if(maxItemsToRetrieve != -1 && counter >= maxItemsToRetrieve ){
				break
			}
			def nextSong = extractNextSong( mixData.id, currentSongId, thumbnailUrl )
			items << nextSong
			if( nextSong.additionalInfo.at_last_track ){
				break
			}
			currentSongId = nextSong.additionalInfo.id
			counter++
		}
		
		return new WebResourceContainer(
			title: mixData.name,
			items: items
		)
	}
	
	private WebResourceItem extractNextSong( int mixId, int songId, String thumbnailUrl ){
		return createItem( getNextTrackData( mixId, songId ), thumbnailUrl )
	}
	
	private WebResourceItem extractFirstSong( int mixId, String thumbnailUrl ){
		return createItem( getFirstTrackData( mixId ), thumbnailUrl )
	}

	private WebResourceItem createItem( Map data, String thumbnailUrl ){
		log( "Creating item: " + 
			data.track.name + " - " + data.track.performer + " (" + data.track.release_name + ")")
		log( "url: " + data.track.track_file_stream_url )
		log( "id: " + data.track.id )
		log( "at_last_track: " + data.at_last_track )
		return new WebResourceItem(
			title: data.track.name + " - " + data.track.performer + " (" + data.track.release_name + ")",
			additionalInfo: [
				track_file_stream_url: data.track.track_file_stream_url,
				id: data.track.id,
				at_last_track: data.at_last_track,
				thumbnailUrl: thumbnailUrl]
		)
	}
	
	private Map convertToJson( String source ){
		String json = URLDecoder.decode(source, "utf-8")
		return new JsonSlurper().parseText(json)
	}
	
	private Map getFirstTrackData(int mixId){
		String infoUrl = "http://8tracks.com/sets/1/play?player=sm&mix_id=" + mixId + "&format=jsonh"
		log( "info url: " + infoUrl)
		String source = openURL( new URL(infoUrl), USER_AGENT )
		log( "info source: " + source)
		return convertToJson( source ).set
		
	}
	private Map getNextTrackData(int mixId, int previousId){
		String url = "http://8tracks.com/sets/1/next?player=sm&mix_id="+ mixId +"&track_id="+ previousId +"&format=jsonh"
		log( "info url: " + url)
		String source = openURL( new URL(url), USER_AGENT )
		log( "info source: " + source)
		return convertToJson( source ).set
						
	}

	@Override
	protected ContentURLContainer extractUrl(WebResourceItem item,
			PreferredQuality quality) {
		// 8 tracks has only one quality.
		return new ContentURLContainer(
			fileType: MediaFileType.AUDIO,
			thumbnailUrl: item.additionalInfo.thumbnailUrl, 
			contentUrl: item.additionalInfo.track_file_stream_url)
	}

	@Override
	public boolean extractorMatches(URL url) {
		String pageSource = openURL(url, USER_AGENT)
		Map mixData = convertToJson((pageSource=~MIX_INFO_REGEX)[0][1])
		return mixData.id != null
	}

	@Override
	public String getExtractorName() {
		return getClass().getName()
	}
	
	static void main(args) {
		def TestUrl = new URL("http://8tracks.com/diil911/those-sumptuous-female-voices")
		EightTracks extractor = new EightTracks()
		println "PluginName               : " + extractor.getExtractorName();
		println "TestMatch                : " + extractor.extractorMatches(TestUrl);
		WebResourceContainer container = extractor.extractItems(TestUrl, -1);
		println "URL                      :" + extractor.extractUrl(container.getItems()[0], PreferredQuality.HIGH)
	}

}
