import groovy.json.JsonSlurper

import org.serviio.library.metadata.*
import org.serviio.library.online.*

/**
 * Vimeo.com content URL extractor plugin. 
 * 
 * Based on youtube_dl Python script (http://rg3.github.com/youtube-dl/)
 * http://code.google.com/p/vimeoxbmc/
 *  
 * @author Petr Nejedly
 *
 */
class Vimeo extends FeedItemUrlExtractor {

    final VALID_ITEM_URL = 'https?://((www|player)\\.)?vimeo\\.com/.*?([0-9]+)'
    final VALID_FEED_URL = '^http(s)*://.*vimeo\\..*$'
	
	private final codecs = [['h264','mp4'], ['vp8','flv'], ['vp6','flv']]
	
    String getExtractorName() {
        return getClass().getName()
    }
    
    boolean extractorMatches(URL feedUrl) {
        return feedUrl ==~ VALID_FEED_URL
    }
    
	public int getVersion() {
		return 2
	}

	ContentURLContainer extractUrl(Map links, PreferredQuality requestedQuality) {
        def linkUrl = links.default
        def contentUrl
        
        def matcher = linkUrl =~ VALID_ITEM_URL
        assert matcher != null
        def videoId = matcher[0][3]
		
		def videoPageHtml = openURL(linkUrl, getFFmpegUserAgent())
		def vphm = videoPageHtml =~ '(?s)\\{config:(.+),assets'
		assert vphm != null
		Map config = new JsonSlurper().parseText(vphm[0][1])
		
		def thumbnailUrl = config.video.thumbnail
		def sig = config.request.signature
		def timestamp = config.request.timestamp
		
		def files = [ 'hd': [], 'sd': [], 'other': []]
		
		for (codecEntry in codecs) {
			def codecName = codecEntry[0]
			def codecExtension = codecEntry[1]
			if( config.video.files.containsKey(codecName) ) {
				def qualities = config.video.files.get(codecName)
				if(qualities.contains('hd')) files['hd'].add([codecName, codecExtension, 'hd'])
				else if(qualities.contains('sd')) files['sd'].add([codecName, codecExtension, 'sd'])
				else files['other'].add([codecName, codecExtension, config.video.files.get(codecName)[0]])
			}
		}

		def selectedVideoQuality = null
		def selectedVideoCodec = null
		def selectedVideoExtension = null
		if(requestedQuality == PreferredQuality.HIGH) {
			if( files['hd'].size() > 0 ) {
				selectedVideoQuality = files['hd'][0][2]
				selectedVideoCodec = files['hd'][0][0]
				selectedVideoExtension = files['hd'][0][1]
			}
		}
		if( selectedVideoQuality == null) {
			for(quality in ['sd','other','hd']) {
				if( files[quality].size() > 0 ) {
					selectedVideoQuality = files[quality][0][2]
					selectedVideoCodec = files[quality][0][0]
					selectedVideoExtension = files[quality][0][1]
					break
				}
			}
		}
		
		contentUrl = "http://player.vimeo.com/play_redirect?clip_id=$videoId&sig=$sig&time=$timestamp&quality=$selectedVideoQuality&codecs=${selectedVideoCodec.toUpperCase()}&type=moogaloop_local&embed_location=" 
		return new ContentURLContainer(contentUrl: contentUrl, thumbnailUrl: thumbnailUrl)
    }
    
    static void main(args) {
		// this is just to test
        Vimeo extractor = new Vimeo()
		
		assert extractor.extractorMatches( new URL("http://vimeo.com/channels/stereoscopy/videos/rss") )
		assert extractor.extractorMatches( new URL("http://vimeo.com/channels/saisouljourns/videos/rss") )
		assert !extractor.extractorMatches( new URL("http://google.com/feeds/api/standardfeeds/top_rated?time=today") )
		
		Map links = ['default': new URL('http://vimeo.com/channels/saisouljourns#18681973')]
		//Map links = ['default': new URL('http://vimeo.com/31100268')]
				
        ContentURLContainer result = extractor.extractUrl(links, PreferredQuality.HIGH)
        println "Result: $result"
    }
}