import groovy.util.XmlParser
import groovy.json.JsonSlurper
import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*

/********************************************************************
 * zonytvcom.info plugin for Serviio
 * 
 * @author X S Inattar
 *
 * URL to use as video webresource: 
 *     - Live Streams: http://www.zengatv.com/home.zenga
 * 
 * Version:
 *    V1: August 27, 2012 - Initial Release - Support for Live Channels
 * 
 ********************************************************************/
 
 class ZengaTV extends WebResourceUrlExtractor {
 
    final VALID_RESOURCE_URL = '^(?:http://)?(?:www\\.)?zengatv\\.com/(.*?)\\.zenga'
    final BASE_URL = 'http://www.zengatv.com/'
    final TITLE = 'ZengaTV'
    final CHANNEL_LIST_EXTRACTOR = '(?s)<li>(.*?)</li>'
    final CHANNEL_TITLE_URL_EXTRACTOR = '<a href="(.*?)" title="(.*?)"   onmouseup='
    final CHANNEL_THUMBNAIL_EXTRACTOR = '<img src="(.*?) height='
    final SWF_URL = 'http://www.zengatv.com/player.swf'
    
    String getExtractorName() {
        return 'zengatv.com'
    }
    
    boolean extractorMatches(URL resourceURL) {
        return resourceURL ==~ VALID_RESOURCE_URL
    }
   
    /**/
    void write_to_log(
        String text
    ) {
        log(TITLE + ' - ' + text)
    }
    /**/
    
    Boolean URLExists(URL fileURL){
        if(((HttpURLConnection) fileURL.openConnection()).getResponseCode() == 404){
            return false
        }
        return true
    }
    
    String process_for_URL(        
        String htmlText,
        String rgxMatcher,
        String baseURL
    ) {       
        def return_val = '-NOTFOUND-'        
        def matcher = htmlText =~ rgxMatcher
        if (matcher.count > 0) {
            return_val = '-URL-' + baseURL + matcher[0][1]
            return_val = return_val.replaceAll(" ", "%20")
        }        
        return return_val
    }        
       
    String process_for_PLAYPATH_STREAMER(
        String htmlText,
        String rgxMatcher,
        String pageUrl,
        String swfUrl
    ) {        
        def return_val = '-NOTFOUND-'        
        def matcher = htmlText =~ rgxMatcher
        if (matcher.count > 0) {
        
            def playpath = matcher[0][1]
            def stream = matcher[0][2]                        
            
            return_val = '-STREAM-' + stream
            return_val = return_val + ' playpath=' + playpath
            return_val = return_val + ' pageUrl=' + pageUrl
            return_val = return_val + ' swfUrl=' + swfUrl
            return_val = return_val + ' live=true'
        }        
        return return_val
    }
    
    String processChannel(
        String channel_url
    )
    {
        def log_text = ''
        def error = ''   
        
        if (!URLExists(new URL(channel_url))) {
            error = '-DEADLINK-'
            log_text = log_text + error
            print error
            write_to_log(log_text)
            return error
        }
        
        def channel_src_text = new URL(channel_url).getText()        
        channel_src_text = channel_src_text.replaceAll('%3A',':')
        channel_src_text = channel_src_text.replaceAll('%2F','/')
        channel_src_text = channel_src_text.replaceAll('&amp;','&')                                         
        channel_src_text = channel_src_text.replaceAll('&quot;','"')                                         
        channel_src_text = channel_src_text.replaceAll('&lt;','<')                                         
        channel_src_text = channel_src_text.replaceAll('&gt;','>')                                                                 
        channel_src_text = channel_src_text.replaceAll('%2D','-')
        
        def channel_stream_url_text = channel_src_text            
        def url_found = 0          
        def loop = 0  
        def base_url = ''
        def current_url = channel_url //channel_src
        def rtmp_url = ''            
        while (url_found == 0) {                  
            
            def returned_url = '-NOTFOUND-'
                        
            if (returned_url == '-NOTFOUND-' ) {
                returned_url = process_for_PLAYPATH_STREAMER(
                    channel_stream_url_text,
                    '<jwplayer:file>(.*?)</jwplayer:file>.*?<jwplayer:streamer>(.*?)</jwplayer:streamer>',
                    channel_url,
                    "http://www.zengatv.com/player.swf"
                )
            }            
            if (returned_url == '-NOTFOUND-') { 
                returned_url = process_for_URL(
                    channel_stream_url_text, 
                    "displayflow\\('(.*?)','player_panel',0\\);",
                    BASE_URL
                )                 
            }
            
            log_text = log_text + returned_url    
            log_text = log_text + ' '
            print returned_url + ' '
            
            if (returned_url == '-NOTFOUND-') {
                error = '-NOTFOUND-'
                write_to_log(log_text)
                return error
            }            
            else if (returned_url.contains("-URL-")) {
                returned_url = returned_url.replaceFirst("-URL-","")
                current_url = returned_url
                if (!URLExists(new URL(current_url))) {
                    error = '-DEADLINK-'
                    log_text = log_text + error
                    print error
                    write_to_log(log_text)
                    return error
                }
                channel_stream_url_text = new URL(current_url).getText()
                channel_stream_url_text = channel_stream_url_text.replaceAll('%3A',':')
                channel_stream_url_text = channel_stream_url_text.replaceAll('%2F','/')
                channel_stream_url_text = channel_stream_url_text.replaceAll('&amp;','&')                                         
                channel_stream_url_text = channel_stream_url_text.replaceAll('&quot;','"')                                                         
                channel_stream_url_text = channel_stream_url_text.replaceAll('%2D','-')
                channel_stream_url_text = channel_stream_url_text.replaceAll('&lt;','<')                                         
                channel_stream_url_text = channel_stream_url_text.replaceAll('&gt;','>')                                                                                                 
            }
            else if (returned_url.contains("-STREAM-")) {
                rtmp_url = returned_url
                url_found = 1
            }         
        }             
        
        write_to_log(log_text)
        
        return rtmp_url   
    }
    
    WebResourceContainer extractItems(URL resourceURL, int maxItemsToRetrieve) {
    
        List<WebResourceItem> items = []
        
        def resource_id_matcher = resourceURL =~ VALID_RESOURCE_URL
        if (resource_id_matcher.count <= 0) {
            write_to_log("Invalid Resource URL")
            return null
        }        
        def resource_id = resource_id_matcher[0][1]
        resource_id = resource_id.toLowerCase();
        def page = ''
        switch (resource_id) {
            case 'home' :
                page = BASE_URL + 'ajaxLive.jsp'
                break
        }
        if (page.size() <= 0) {
            write_to_log("Invalid Resource URL")
            return null
        }
        
        def pageURL = new URL(page)
        if (URLExists(pageURL) == false) {
            write_to_log("Invalid Resource URL")
            return null
        }        
        
        def resource_text = pageURL.getText()                
        
        def channel_list_matcher = resource_text =~ CHANNEL_LIST_EXTRACTOR
        def channel_count = channel_list_matcher.count
        println channel_count
        //for (channel_number in 36..<40) {
        for (channel_number in 0..<channel_count) {
            def channel_title_url_matcher = channel_list_matcher[channel_number][1] =~ CHANNEL_TITLE_URL_EXTRACTOR
            def channel_url = BASE_URL + channel_title_url_matcher[0][1]            
            def channel_title = channel_title_url_matcher[0][2]
            
            def channel_thumbnail_matcher = channel_list_matcher[channel_number][1] =~ CHANNEL_THUMBNAIL_EXTRACTOR
            def channel_image = BASE_URL + channel_thumbnail_matcher[0][1]                        
            
            items << new WebResourceItem(title: channel_title, 
                additionalInfo: [channelURL: channel_url.replaceAll(" ", "%20"), 
                    thumbnailURL: channel_image, 
                    cacheKey: TITLE + '_' + resource_id + '_' + channel_title.replaceAll(" ", "_"),
                    live: resource_id == "home" ? true : false
                ]
            )
        }                
        
        return new WebResourceContainer(title: TITLE, items: items)
    }
    
    ContentURLContainer extractUrl(WebResourceItem item, PreferredQuality requestedQuality) {
    
        def rtmp_url = processChannel(item.additionalInfo.channelURL)
        if (rtmp_url.contains('-STREAM-')) {
            rtmp_url = rtmp_url.replaceFirst("-STREAM-", "")
        }
        else {
            return null
        }
                
        return new ContentURLContainer(contentUrl: rtmp_url, 
            thumbnailUrl: item.additionalInfo.thumbnailURL, 
            expiresImmediately: true, 
            cacheKey : item.additionalInfo.cacheKey,
            live: item.additionalInfo.live)    
    }
    
    static void main(args) {
        
        ZengaTV extractor = new ZengaTV()
        
        WebResourceContainer container = extractor.extractItems( new URL("http://www.zengatv.com/home.zenga"), 5)
        /**/
        container.getItems().each {
//            println it
            ContentURLContainer result = extractor.extractUrl(it, PreferredQuality.MEDIUM)
            println result 
        }
       /**/                  
    }
 }