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.4
 *
 * 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 http://www.southparkstudios.com/feeds/full-episode/carousel/16/
    final VALID_FEED_URL = '^http://www.southparkstudios.com/feeds/full-episode/|^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"

    // Resource Container
    WebResourceContainer extractItems(URL resourceUrl, int maxItems) {
        def southpark = resourceUrl.toString() ==~ "^http://www.southparkstudios.com/feeds/full-episode/carousel/\\d{1,2}/.*"
        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)
            print "SP!"
            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{
            print "NOPE!"
            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)


        Pattern regex = Pattern.compile("(?s)\\r(.*)");
        Matcher regexMatcher = regex.matcher(data);
        regexMatcher.find()

        //Fix invalid JSON :(
        def json = regexMatcher.group(1).replaceAll('season:', '\"season\":').replaceAll('episode:', '\"episode\":')
                .replaceAll('title:', '\"title\":')
                .replaceAll('description:', '\"description\":')
                .replaceAll('tags:', '\"tags\":')
                .replaceAll('thumbnail:', '\"thumbnail\":')
                .replaceAll('thumbnail_larger:', '\"thumbnail_larger\":')
                .replaceAll('thumbnail_190:', '\"thumbnail_190\":')
                .replaceAll('id:', '\"id\":')
                .replaceAll('url:', '\"url\":')
                .replaceAll('airdate:', '\"airdate\":')
                .replaceAll('episodenumber:', '\"episodenumber\":')
                .replaceAll('available:', '\"available\":')
                .replaceAll('when:', '\"when\":')
                .replaceAll('\'', '\"')
                .replaceAll('specialFeatureTitle:', '\"specialFeatureTitle\":')
                .replaceAll('specialFeatureImage:', '\"specialFeatureImage\":')
                .replaceAll('specialFeatureLink:', '\"specialFeatureLink\":')

        def result = slurper.parseText(json)
        
        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("MM.dd.yyyy", Locale.US)

            for (act in episode_data_xml.channel.item) {
                //http://www.southparkstudios.com/feeds/video-player/mediagen?uri=mgid%3Aarc%3Aepisode%3Asouthparkstudios.com%3A1438cfb6-ad31-4ea8-be61-e5139dba1f13&suppressRegisterBeacon=true&acceptMethods=fms,hdn1,hds
                String video_stream_act = act.'media:group'.'media:category'.findAll {it.'@scheme' == "urn:mtvn:id"}[0].text()
                String video_stream_act_source = "http://www.southparkstudios.com/feeds/video-player/mediagen?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(episode.airdate), 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) {
            //print "http://www.thedailyshow.com/feeds/video_player/mrss/?uri=mgid:cms:episode:${show_id}:${episode}&type=network&geo=US"
            def episode_data = openURL(new URL("http://www.thedailyshow.com/feeds/video_player/mrss/?uri=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.southparkstudios.com/feeds/full-episode/carousel/16/dc400305-d548-4c30-8f05-0f27dc7e0d5c"
        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



    }
}

