import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*
import groovy.util.XmlParser
import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*
import java.util.regex.PatternSyntaxException
import java.util.regex.Pattern
import java.util.regex.Matcher
import java.text.SimpleDateFormat
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
/**
 * WebResource plugin for Comedy Central
 * @author insane822
 * Version 1.0.3
 *
 * Currently Supports:
 * The Daily Show: http://www.thedailyshow.com/full-episodes
 * Colbert Nation: http://www.colbertnation.com/full-episodes/
 * South Park: http://www.southparkstudios.com/feeds/full-episode/carousel/16/342853. Replace 16 with the season you want to add.
 */

class ComedyCentral extends WebResourceUrlExtractor {

    // Feed URL regex
    final VALID_FEED_URL = '^http://www.southparkstudios.com/feeds/full-episode/carousel/\\d{1,2}/\\d{6}|^http://www.colbertnation.com/full-episodes/|^http://www.thedailyshow.com/full-episodes/'

    // Plug-in name
    String getExtractorName() {
        return 'ComedyCentral'
    }

    // Valid URL
    boolean extractorMatches(URL feedUrl) {
        return feedUrl ==~ VALID_FEED_URL
    }

    String user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.39 Safari/537.4"

    // Resource Container
    WebResourceContainer extractItems(URL resourceUrl, int maxItems) {
        def southpark = resourceUrl.toString() ==~ "^http://www.southparkstudios.com/feeds/full-episode/carousel/\\d{1,2}/\\d{6}"
        def thedailyshow = resourceUrl.toString() ==~ "^^http://www.thedailyshow.com/full-episodes/"
        def colbertnation = resourceUrl.toString() ==~ "^http://www.colbertnation.com/full-episodes/"

        if (southpark) {
            List<WebResourceItem> items = getSouthPark(resourceUrl)
            return new WebResourceContainer(title: "South Park", items: items)
        } else if (thedailyshow) {
            List<WebResourceItem> items = getFeeds("thedailyshow.com")
            return new WebResourceContainer(title: "The Daily Show", items: items)
        } else if (colbertnation) {
            List<WebResourceItem> items = getFeeds("colbertnation.com")
            return new WebResourceContainer(title: "The Colbert Report ", items: items)
        } else{
            return new WebResourceContainer(title: false)
        }

    }
    


    // Content URL
    ContentURLContainer extractUrl(WebResourceItem item, PreferredQuality requestedQuality) {

            URL stream_data = new URL(item.additionalInfo.stream_list)
            def stream_data_xml = new XmlParser().parseText(openURL(stream_data, user_agent))

            List mediaItems = stream_data_xml.video.item.rendition
            List sortedItems = mediaItems.sort { it.'@bitrate'.toInteger() }
            Node selectedMediaItem = findSuitableItem(sortedItems, requestedQuality)
            
            Pattern regex = Pattern.compile("(gsp.comedystor.*)");
            Matcher regexMatcher = regex.matcher(selectedMediaItem.src.text());
            regexMatcher.find()

            def stream_path = regexMatcher.group(1)

            String swf = "http://media.mtvnservices.com/player/prime/mediaplayerprime.1.11.3.swf"
            String cdn = "rtmpe://viacomspstrmfs.fplive.net:1935/viacomspstrm"
            String mp4_stream = "http://mtvnmobile.vo.llnwd.net/kip0/_pxn=0+_pxK=18639+_pxE=/44620/mtvnorigin/${stream_path}"
            String contentUrl = mp4_stream
            String cacheKey = mp4_stream

            return new ContentURLContainer(contentUrl: contentUrl, expiresImmediately: false, thumbnailUrl: item.additionalInfo.thumbnailUrl)
    }

    def getSouthPark(URL resourceUrl) {
        def slurper = new JsonSlurper()
        def data = openURL(resourceUrl, user_agent)
		data = data.substring(data.indexOf("*/")+4);
		data = data.replace('season:', '\"season\":');
		data = data.replace('episode:', '\"episode\":');
		data = data.replace('title:', '\"title\":');
		data = data.replace('description:', '\"description\":');
		data = data.replace('tags:', '\"tags\":');
		data = data.replace('thumbnail:', '\"thumbnail\":');
		data = data.replace('thumbnail_larger:', '\"thumbnail_larger\":');
		data = data.replace('thumbnail_190:', '\"thumbnail_190\":');
		data = data.replace('id:', '\"id\":');
		data = data.replace('url:', '\"url\":');
		data = data.replace('airdate:', '\"airdate\":');
		data = data.replace('episodenumber:', '\"episodenumber\":');
		data = data.replace('available:', '\"available\":');
		data = data.replace('airdate:', '\"airdate\":');
		data = data.replace('when:', '\"when\":');
		data = data.replace('\'', '\"');
		data = data.replace('specialFeatureTitle:', '\"specialFeatureTitle\":');
		data = data.replace('specialFeatureImage:', '\"specialFeatureImage\":');
		data = data.replace('specialFeatureLink:', '\"specialFeatureLink\":');

        def result = slurper.parseText(data)

        List<WebResourceItem> items = []

        for (episode in result.season.episode) {
            // If this episode is unavailable, skip it.
            if (episode.available != "true") {
                continue
            }


            def episode_data = openURL(new URL("http://www.southparkstudios.com/feeds/video-player/mrss/mgid:cms:content:southparkstudios.com:${episode.id}"), user_agent).replaceAll(" & ", " &amp; ")
            def episode_data_xml = new XmlParser().parseText(episode_data)
            def Map act_list = ["title":false, "url": false, "thumbnail":false]
            // dateFormat author Mike_Metro
            def SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.US)

            for (act in episode_data_xml.channel.item) {

                String video_stream_act = act.'media:group'.'media:category'.findAll {it.'@scheme' == "urn:mtvn:id"}[0].text()
                String video_stream_act_source = "http://services.comedycentral.com/global/feeds/entertainment/media/mediaGenEntertainment.jhtml?uri=${video_stream_act}&show=southpark"
                String video_release_date = act.'media:group'.'media:category'.findAll {it.'@scheme' == "urn:mtvn:display:date"}[0].text()
                String thumbnail = episode.thumbnail_190

                items << new WebResourceItem(title: "${episode.episodenumber} - ${act.title.text()}", releaseDate: dateFormat.parse(video_release_date), additionalInfo: [stream_list: video_stream_act_source, thumbnailUrl: thumbnail.replaceAll('width=190', 'width=480')])

            }

        }

        return items
    }

    def getFeeds(show_id) {

        List<WebResourceItem> items = []
        List episodes = []

        //Get all current episodes
        for (week in 0..4) {
            def feed_url
            def m
            if (show_id == "thedailyshow.com"){
                def week_feed = openURL(new URL("http://www.thedailyshow.com/full-episodes/"), "wonka")
                def week_feed_match = week_feed =~ /full-episode\/showcase\/(\d{6})\/\d{1}\/(\d{6})/

                feed_url = "http://www.thedailyshow.com/feeds/full-episode/showcase/${week_feed_match[0][1]}/${week}/${week_feed_match[0][2]}"
                def html = openURL(new URL(feed_url), user_agent)
                m = html =~ /frag_(\d{6})/
            } else {
                def week_feed = openURL(new URL("http://www.colbertnation.com/full-episodes/"), "wonka")
                def week_feed_match = week_feed =~ /episode_showcase\/(\d{6})\/\d{1}\/(\d{6})/

                feed_url = "http://www.colbertnation.com/feeds/episode_showcase/${week_feed_match[0][1]}/${week}/${week_feed_match[0][2]}"
                def html = openURL(new URL(feed_url), user_agent)
                m = html =~ /episode_(\d{6})/
            }

            for (episode in m) {
                episodes << episode[1]
            }
        }

        for (episode in episodes) {
            def episode_data = openURL(new URL("http://www.southparkstudios.com/feeds/video-player/mrss/mgid:cms:episode:${show_id}:${episode}&type=network&geo=US"), user_agent).replaceAll(" & ", " &amp; ")
            def episode_data_xml = new XmlParser().parseText(episode_data)

            for (act in episode_data_xml.channel.item) {

                String video_stream_act = act.'media:group'.'media:category'.findAll {it.'@scheme' == "urn:mtvn:id"}[0].text()
                String video_stream_act_source = "http://services.comedycentral.com/global/feeds/entertainment/media/mediaGenEntertainment.jhtml?uri=${video_stream_act}&show=southpark"
                String video_release_date = act.'media:group'.'media:category'.findAll {it.'@scheme' == "urn:mtvn:display:date"}[0].text()
                String thumbnail = episode_data_xml.channel.image.url
                def SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.US)

                items << new WebResourceItem(title: "${act.title.text()}", releaseDate: dateFormat.parse(video_release_date), additionalInfo: [stream_list: video_stream_act_source, thumbnailUrl: thumbnail.replaceAll('width=190', 'width=480')])

            }

        }

        return items
    }



    // @author Petr Nejedly
    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.floor(items.size()/2).toInteger())
        } else {
            // best quality, take the last url
            return items.last()
        }
    }
    

    // This is just to test, not actual code used for the plugin
    static void main(args) {
        ComedyCentral extractor = new ComedyCentral()

        String series_url = "http://www.thedailyshow.com/full-episodes/"
        WebResourceContainer container = extractor.extractItems( new URL(series_url), -1)
        //print container
        container.getItems().each {
            ContentURLContainer result = extractor.extractUrl(it, PreferredQuality.HIGH)
            println result
        }
        println container



    }
}

