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

/********************************************************************
 * Content URL extractor for ABC + ABC Family Video Feeds
 * Logic based on XBMC -> BlueCop Repo -> Free Cable -> ABC (& ABC Family)
 * 
 * @author X S Inattar
 *
 * Must be installed as a Video WebResource
 * Sample URLs: 
 *    Popular Episodes: http://cdn.abc.go.com/vp2/ws-supt/s/syndication/2000/rss/001/001/-1/PL5555335/-1/-1/-1/-1
 *    Latest Episodes: http://cdn.abc.go.com/vp2/ws-supt/s/syndication/2000/rss/001/001/-1/PL5515990/-1/-1/-1/-1
 *    Comedies: http://cdn.abc.go.com/vp2/ws-supt/s/syndication/2000/rss/001/001/-1/PL55149155/-1/-1/-1/-1
 * Version:
 *    V1: June 30, 2012 - Initial Release
 *
 ********************************************************************/
 
 class ABC extends FeedItemUrlExtractor {
     
    final VALID_FEED_URL = '^http(s)*://cdn.abc.go.com/vp2/ws-supt/s/syndication/2000/rss/.*$'
    final VIDEO_ID_EXTRACTOR = 'http://abc.*.go.com/watch/.*?/.*?/(.*?)/.*?'
    final VIDEO_DETAILS = 'http://cdn.abc.go.com/vp2/ws/s/contents/2004/utils/video/mov/13/9024/%s/432'
    final SUPPORTED_PROVIDERS = ['Level3']
    final SUPPORTED_PROTOCOLS = ['rtmp']
    final SWF_URL = 'http://ll.static.abc.com/m/vp2/prod/flash/VP2_05040017_0_1254.swf'
    final THUMBNAIL_EXTRACTOR = '<link href="(.*?)" rel="image_src"'
    
    String getExtractorName() {
        return 'ABC'
    }
    
    boolean extractorMatches(URL feedUrl) {
        return feedUrl ==~ VALID_FEED_URL
    }
    
    ContentURLContainer extractUrl(Map links, PreferredQuality requestedQuality) {
        def linkUrl = links.default
        def contentUrl
        def thumbnailUrl
        
        def linkPageText = linkUrl.getText()
        def thumbnailUrlMatcher = linkPageText =~ THUMBNAIL_EXTRACTOR
        if (thumbnailUrlMatcher.count > 0) {
            thumbnailUrl = thumbnailUrlMatcher[0][1]
        }
        
        def videoIdMatcher = linkUrl =~ VIDEO_ID_EXTRACTOR
        def videoId = videoIdMatcher[0][1]
        
        def videoDetailsUrl = new URL(String.format(VIDEO_DETAILS, videoId))
        def videoDetails = videoDetailsUrl.getText()
        
        def videoDetailsNode = new XmlParser().parseText(videoDetails)
        
        Node hostNode = videoDetailsNode.resources.host.find{ SUPPORTED_PROVIDERS.contains(it.'@provider') && SUPPORTED_PROTOCOLS.contains(it.'@protocol')}
        if (hostNode == null) {
            log('Could not find content URL')
            return null
        }     
        
        List videoSrcNodes = videoDetailsNode.videos.video.findAll{ it.'@src' ==~ '.+.*' }
        if ( videoSrcNodes.size() <= 0) {
            log('Could not find content URL')
            return null
        }     
        
        List sortedVideoSrcNodes = videoSrcNodes.sort { it.'@bitrate'.toInteger() }
        
        Node selectedVideoSrc = findSuitableItem(sortedVideoSrcNodes, requestedQuality)
        
        contentUrl = "rtmp://${hostNode.'@url'}/${hostNode.'@app'} playpath=${selectedVideoSrc.'@src'} swfUrl=${SWF_URL} swfVfy=0"
        
        def cacheKey = "ABC_${videoId}_${requestedQuality}"
        
        return new ContentURLContainer(contentUrl: contentUrl, thumbnailUrl: thumbnailUrl, expiresImmediately: true, cacheKey: cacheKey)
    }
    
    def Node findSuitableItem(List items, PreferredQuality requestedQuality) {
        if(requestedQuality == PreferredQuality.LOW) {
            // worst quality, get the first from the list
            return items.head()
        } else if (requestedQuality == PreferredQuality.MEDIUM) {
            // get item from the middle
            return items.get(Math.round(items.size()/2).toInteger())
        } else {
            // best quality, take the last url
            return items.last()
        }
    }
        
    static void main(args) {
        // this is just to test
        ABC extractor = new ABC()
        
        assert extractor.extractorMatches( new URL("http://cdn.abc.go.com/vp2/ws-supt/s/syndication/2000/rss/001/001/-1/PL5555335/-1/-1/-1/-1") )
        assert !extractor.extractorMatches( new URL("http://google.com/feeds/api/standardfeeds/top_rated?time=today") )
        
        Map videoLinks = ['default': new URL('http://abc.go.com/watch/dont-trust-the-b-----in-apt-23/SH55126557/VD55185758/pilot?rfr=rss')]
        ContentURLContainer result = extractor.extractUrl(videoLinks, PreferredQuality.LOW)
        println "Result: $result"    
        
        Map videoLinks1 = ['default': new URL('http://abcfamily.go.com/watch/switched-at-birth/SH55120583/VD55183814/venus-cupid-folly-and-time?rfr=rss')]
        ContentURLContainer result1 = extractor.extractUrl(videoLinks1, PreferredQuality.HIGH)
        println "Result: $result1"        
    }  
 }