import groovy.json.JsonSlurper

import groovy.json.JsonSlurper

import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*

/**
 * WebResource extractor plugin for tunein.com.
 * 
 * @author Petr Nejedly
 *
 */
class TuneIn extends WebResourceUrlExtractor {
	
	final VALID_FEED_URL = '^(?:https?://)?(?:www\\.)?tunein\\.com/radio/.+'
	
	String getExtractorName() {
		return 'Tune In'
	}
	
	boolean extractorMatches(URL feedUrl) {
		return feedUrl ==~ VALID_FEED_URL
	}
	
	WebResourceContainer extractItems(URL resourceUrl, int maxItems) {
		String html = resourceUrl.getText()
		
		def titleMatcher = html =~ '(?s)<h1>(.+?)<'
		String pageTitle = titleMatcher[0][1].trim()
		
		List<WebResourceItem> items = []
		
		def stationMatcher = html =~ '(?s)addPreset\\(.+?,(.+?),.*?\'(.*?)\''
		def itemsAdded = 0;
		for( int i = 0; i < stationMatcher.size() && (maxItems == -1 || itemsAdded < maxItems); i++ ) {
			String stationId = stationMatcher[i][1].trim()
			String stationTitle = stationMatcher[i][2].trim()			
			WebResourceItem item = new WebResourceItem(title: stationTitle, additionalInfo: ['stationId':stationId])
			items << item
			itemsAdded++			
		}
			
		return new WebResourceContainer(title: pageTitle, items: items)
	}
	
	ContentURLContainer extractUrl(WebResourceItem item, PreferredQuality requestedQuality) {		
		String stationId = item.getAdditionalInfo()['stationId']
		assert stationId != null
		
		String playerHtml = new URL("http://tunein.com/tuner/?StationId=$stationId&").getText()
		
		def jsonMatcher = playerHtml =~ '(?s)RadioTime.tuneData =.*?(\\{.+?)RadioTime\\.'
		String jsonCode = jsonMatcher[0][1].trim()
		def json = new JsonSlurper().parseText(jsonCode)
		Map jsonResult = (Map) json;
		// thubmnail
		String thumbnailUrl = jsonResult['Logo']
		// streams, get required quality
		List streams = jsonResult['Streams']
		// only get streams that are represented as playlists and are live streams
		streams = streams.findAll { it -> it['Type'] == 'Live' && it['MediaType'] == 'MP3' }
		if( streams.size() > 0 ) {
			// ignore quality, audio bitrate is too low to make any difference, deliver the best available
			streams = streams.sort { it -> it['Bandwidth'].toInteger() }
			Map selectedStream = streams.last()
			String playlistUrl = selectedStream['Url']
			String streamUrl = getUrlFromPlaylist(new URL(playlistUrl))
			return new ContentURLContainer(fileType: MediaFileType.AUDIO, contentUrl: streamUrl, thumbnailUrl: thumbnailUrl, live: true)
		} else {
			log('No suitable streams found')
		}
	}
	
	/**
	 * Supports m3u playlists ATM
	 */
	protected getUrlFromPlaylist(URL playlistUrl) {
		assert playlistUrl != null
		
		String playlist = playlistUrl.getText()
		if(playlist.toLowerCase().startsWith("<asx")) {
			// asx playlists not supported
			return null			
		} else {
			// assume m3u playlist
		    List lines = playlist.readLines()
			String url = lines[0]
			if(url.startsWith ('[playlist]') ) {
				for(String line : lines) {
					if(line.startsWith('File1')) {
						url = line.substring(line.indexOf ('=') + 1).trim()
						break
					}
				}
			}
			if (url.endsWith('.')) {
				url = url.substring(0, url.size()-1)
			}
			if(url.indexOf('.m3u') > -1 || url.indexOf('.pls') > -1) {
				return getUrlFromPlaylist(new URL(url))
			}
			return url
		}
	}
	
	static void main(args) {
		// this is just to test
		TuneIn extractor = new TuneIn()
				
		assert extractor.extractorMatches( new URL("http://tunein.com/radio/London-United-Kingdom-r100780/?qlc=1") )
		assert !extractor.extractorMatches( new URL("http://google.com/feeds/api/standardfeeds/top_rated?time=today") )
		
		WebResourceContainer container = extractor.extractItems( new URL("http://tunein.com/radio/London-United-Kingdom-r100780/?qlc=1"), -1)
		println container
		
		ContentURLContainer result = extractor.extractUrl(container.getItems()[2], PreferredQuality.MEDIUM)
		print result
		
		//println extractor.getUrlFromPlaylist (new URL("http://stream.radiotime.com/listen.stream?streamId=1045956&rti=dihyG20zJlYQXB09HBdHXE8gQV4QHBwvSwUAV11OJg0ZThZ7ZFBYDFEDJn8QRlU0CwdPUFNDRG5FEFF0Ek5dEFYSXXRqGAVEBUUEUlhRYQ0%3d%7e%7e%7e"))
	}
}