import groovy.util.XmlParser
import groovy.json.JsonSlurper
import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*

/********************************************************************
 * turbotv.in plugin for Serviio
 * 
 * @author X S Inattar
 *
 * URL to use as video webresource: http://www.turbotv.in/
 * 
 * Version:
 *    V1: - Sep 28, 2012 - Initial Release
 *    V2: - Oct 12, 2012 - 
 * 
 ********************************************************************/
 
 class TurboTVIndia extends WebResourceUrlExtractor {
 
    final VALID_RESOURCE_URL = '^(?:http://)?(?:www\\.)?turbotv.in/'
    final BASE_URL = ''
    final BASE_IMAGE_URL = ""
    final TITLE = 'TURBOTV.IN'
    final CHANNEL_LIST_EXTRACTOR = '<liclass="page\\_item page-item-..."><ahref="(.*?)">(.*?)</a></li>'
    
    
    String getExtractorName() {
        return 'turbotv.in'
    }
    
    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
    }
    
    Boolean channelOffline(
        String htmlText, 
        String offlineChecker
    ) {        
        def offline_check = htmlText =~ offlineChecker
        if (offline_check.count > 0) {
            return true
        }
        return false
    }         
    
    Boolean streamNotSupported(
        String htmlText, 
        String streamNotSupportedChecker
    ) {        
        def notsupported_check = htmlText =~ streamNotSupportedChecker
        if (notsupported_check.count > 0) {
            return true
        }
        return false
    }
    
    String modify_playpath_based_on_page_url(String playpath, String pageURL) {
        def actual_playpath = playpath                
        
        return actual_playpath
    }
    
    String modify_playpath_based_on_swf_url(String playpath, String swfURL) {
        def actual_playpath = playpath
        
        return actual_playpath
    }
    
    String fix_playpath(String playpath) {
        def actual_playpath = playpath
        
        actual_playpath = actual_playpath.replaceAll(".flv", "")
        actual_playpath = java.net.URLDecoder.decode(actual_playpath)
        
        return actual_playpath
    } 
        
    String redirect_to_actual_stream(String stream) {
        def actual_stream = stream        
        
        return actual_stream
    }
    
    String modify_stream_based_on_page_and_playpath(String stream, String pageURL, String playpath) {
        def actual_stream = stream                
                
        return actual_stream
    }
    
    String modify_stream_based_on_swf_url(String stream, String swfURL) {
        def actual_stream = stream               
        
        return actual_stream
    }  
    
    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 return_val
    }
    
    String process_for_PLAYPATH(
        String htmlText,
        String rgxMatcher,
        String[] streamURLs,
        String baseURL,
        String swfURL        
    ) {        
        def return_val = '-NOTFOUND-'        
        def matcher = htmlText =~ rgxMatcher
		println rgxMatcher
        if (matcher.count > 0) {
            
            def pageURL = baseURL + matcher[0][1]
            
            def playpath = fix_playpath(matcher[0][1])            
            
            def stream = streamURLs[ (int)(System.currentTimeMillis() % streamURLs.size()) ]
            stream = modify_stream_based_on_page_and_playpath(stream, pageURL, playpath)
            
            playpath = modify_playpath_based_on_page_url(playpath, pageURL)
            playpath = modify_playpath_based_on_swf_url(playpath, swfURL)
            
            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=1'
        }        
        return return_val
    }
    
    String process_for_SWF_STREAMER_PLAYPATH(
        String htmlText,
        String rgxMatcher,
        String pageUrl
    ) {        
        def return_val = '-NOTFOUND-'    
		def rgxMatcher1 =   'ping.src.*?&streamer=(.*?)&.*?&file=(.*?)&'
        def matcher = htmlText =~ rgxMatcher
		def matcher1 = htmlText =~ rgxMatcher1
        if (matcher.count > 0) {
            def swfUrl = matcher[0][1] + '.swf'
			def playpath = fix_playpath(matcher[0][3])
			def stream = matcher[0][2]
			if (stream.trim() == "" & matcher1.count > 0){
				stream = matcher1[0][1]
                playpath = fix_playpath(matcher1[0][2])
			}
            stream = modify_stream_based_on_page_and_playpath(stream, pageUrl, playpath)
            stream = modify_stream_based_on_swf_url(stream, swfUrl)
            stream = redirect_to_actual_stream(stream)
            
            
            playpath = modify_playpath_based_on_page_url(playpath, pageUrl)
            playpath = modify_playpath_based_on_swf_url(playpath, swfUrl)
            
            return_val = '-STREAM-' + stream.replaceAll("rtmp://65.49.77.153/redirect","rtmp://50.7.128.148:1935/base2").replaceAll("rtmp://65.49.77.251/redirect","rtmp://50.7.130.43:1939/base2").replaceAll("rtmp://65.49.77.252/redirect","rtmp://50.7.130.42:1940/base2")
            return_val = return_val + ' playpath=' + playpath
            return_val = return_val + ' pageUrl=' + pageUrl
            return_val = return_val + ' swfUrl=' + swfUrl
            return_val = return_val + ' live=1'
        }        
        return return_val
    }
    
    String process_for_SWF_PLAYPATH_STREAMER(
        String htmlText,
        String rgxMatcher,
        String pageUrl
    ) {        
        def return_val = '-NOTFOUND-'        
        def matcher = htmlText =~ rgxMatcher
        if (matcher.count > 0) {
            
            def swfUrl = matcher[0][1] + '.swf'
            def playpath = fix_playpath(matcher[0][2])
            def stream = matcher[0][3]
            stream = modify_stream_based_on_page_and_playpath(stream, pageUrl, playpath)
            stream = modify_stream_based_on_swf_url(stream, swfUrl)
            stream = redirect_to_actual_stream(stream)
            
            playpath = modify_playpath_based_on_page_url(playpath, pageUrl)
            playpath = modify_playpath_based_on_swf_url(playpath, swfUrl)
            
            return_val = '-STREAM-' + stream.replaceAll("rtmp://65.49.77.251/redirect","rtmp://50.7.130.43:1939/base2").replaceAll("rtmp://65.49.77.252/redirect","rtmp://50.7.130.42:1940/base2")
            return_val = return_val + ' playpath=' + playpath
            return_val = return_val + ' pageUrl=' + pageUrl
            return_val = return_val + ' swfUrl=' + swfUrl
            return_val = return_val + ' live=1'
        }        
        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 = openURL( new URL(channel_url),
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1"
            )        
        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) {
        
            if (channelOffline(channel_stream_url_text, '<h1 class="center">This channel is offline\\.</h1>')
                || channelOffline(channel_stream_url_text, '<h4 class=.*?THIS CHANNEL IS CURRENTLY OFFLINE</h4>')
                ) {
                error = '-OFFLINE-'
                log_text = log_text + error
                print error
                write_to_log(log_text)
                return error
            }
            
            if (streamNotSupported(channel_stream_url_text, '<media url="rtmfp://.*?/>')
                || streamNotSupported(channel_stream_url_text, '<script.*?src=".*?player\\.ooyala\\.com.*?"></script>')                    
                ) {
                error = '-NOTSUPPORTED-'
                log_text = log_text + error
                print error
                write_to_log(log_text)
                return error
            }
            
            def returned_url = '-NOTFOUND-'     
            
            if (returned_url == '-NOTFOUND-' ) {                                  
                returned_url = process_for_SWF_STREAMER_PLAYPATH(
                    channel_stream_url_text,
                    '<script.*?"flashplayer":"(.*?).swf".*?"streamer":"(.*?)".*?"file":"(.*?)"',
                    current_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 = openURL( new URL(current_url), 
                    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1"
                    )
//                channel_stream_url_text = channel_stream_url_text.replaceAll("\n","")
//                channel_stream_url_text = channel_stream_url_text.replaceAll("\r","")
                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;','>')                                                                 
                
                
                /**                
                    println channel_stream_url_text
                    println ''
                    println ''                        
                    println ''
                    println ''
                    println ''                                                                                        
                /**/
            }
            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 = []

        if (URLExists(resourceURL) == false) {
            write_to_log("Invalid Resource URL")
            return null
        }        

        def resource_text = openURL(resourceURL,
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1"
            )

        resource_text = resource_text.replaceAll("\n","")
        resource_text = resource_text.replaceAll("\r","")         

        def channel_list_matcher = resource_text =~ CHANNEL_LIST_EXTRACTOR
        def channel_count = channel_list_matcher.count
        for (channel_number in 0..<channel_count) {
        //for (channel_number in 0..<10) {            
            def channel_url = channel_list_matcher[channel_number][1]
            
            if (channel_url.contains("index.php")) {
                continue;
            }
                        
            def channel_image = ""                                                
            
            def channel_title = channel_list_matcher[channel_number][2]            
            
            def channel_cache_key = channel_title                        
            
            print channel_title
            //processChannel(BASE_URL + channel_url)
            println ''
            
            items << new WebResourceItem(title: channel_title, 
                additionalInfo: [channelURL: BASE_URL + channel_url, 
                    thumbnailURL: BASE_IMAGE_URL + channel_image, 
                    cacheKey: TITLE + '_' + channel_cache_key
                ]
            )
        }                
        
        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: true
            )    
    }
    
    static void main(args) {
        
        TurboTVIndia extractor = new TurboTVIndia()
        
        WebResourceContainer container = extractor.extractItems( new URL("http://www.turbotv.in/"), 5)
        /**/
        container.getItems().each {
            ContentURLContainer result = extractor.extractUrl(it, PreferredQuality.MEDIUM)
            println result
            println ''
        }
       /**/                  
    }
 }