import org.serviio.library.online.WebResourceUrlExtractor
import org.serviio.library.online.WebResourceContainer
import org.serviio.library.online.PreferredQuality
import groovy.json.JsonSlurper
import org.serviio.library.online.WebResourceItem
import org.serviio.library.online.ContentURLContainer
import org.serviio.library.metadata.MediaFileType
/**
 * WebResource extractor Serviio plugin for www.ted.com
 *
 * @author Michael Mishalov
 * @version 2.1
 */
class TED extends WebResourceUrlExtractor {
    /////////////////////////////////////////////////////[CONSTANTS]/////////////////////////////////////////////////////
    final static VALID_WEB_RESOURCE_URL                     = '^(?:http?://)?(?:www\\.)?ted.com/talks/.*'
    final static USER_AGENT                                 = 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1'
    final static METADATA_RESOURCE_REGEX                    = /(?s)"playlist":"(.*?)"/
    final static RELEASE_DATE_REGEX                       = /(?s)"video:release_date" content="(.*?)"/
    final static DEFAULT_VIDEO_DOMAIN                       = "http://video.ted.com/"
    //////////////////////////////////////////////////////[METHODS]//////////////////////////////////////////////////////
    @Override
    protected org.serviio.library.online.WebResourceContainer extractItems(URL url, int i) {
        def pages = url.toString().split(";")
        List<WebResourceItem> items = []
        pages.each {
            String pageSource = openURL(new URL(it), USER_AGENT)
            String json = ((pageSource=~METADATA_RESOURCE_REGEX)[0]-null)[-1].toString().trim()
            long releaseDate = Long.parseLong(((pageSource=~RELEASE_DATE_REGEX)[0]-null)[-1].toString().trim())*1000;
            json = new URLDecoder().decode(json)
            Map data =(Map) new JsonSlurper().parseText(json)
            items << createItem(data,releaseDate)
        }
        return new WebResourceContainer(title: String.format("%d talk%s from TED.com",pages.length,pages.length>1?"s":""), items: items)
    }

    /**
     * Creates additional info map for web resource item
     * @param videos  ArrayList contains data about all available qualities of fetched video
     * @return Map contains as key  video bitrate and as value link to video
     */
    private WebResourceItem createItem(Map data, long releaseDate){
        Map<Object,Object> additionalInfo = new HashMap<String, Object>();
        additionalInfo.put("resources",data.talks.resource[0])
        additionalInfo.put("thumbnailURL", data.talks.thumbnailURL[0])
        String title = data.talks.title[0];
        return new WebResourceItem(title: title, releaseDate: new Date(releaseDate), additionalInfo: additionalInfo)
    }

    @Override
    protected org.serviio.library.online.ContentURLContainer extractUrl(org.serviio.library.online.WebResourceItem webResourceItem, org.serviio.library.online.PreferredQuality preferredQuality) {
        String contentUrl
        def resources = webResourceItem.additionalInfo.get("resources")
        switch (preferredQuality){
            case PreferredQuality.HIGH:
                contentUrl = resources[0].file.substring(4)
                break
            case PreferredQuality.MEDIUM:
                contentUrl = resources[(int)(Math.round(resources.size()/2)-1)].file.substring(4)
                break
            case PreferredQuality.LOW:
                contentUrl = resources[-1].file.substring(4)
                break
        }
        return new ContentURLContainer(fileType: MediaFileType.VIDEO,thumbnailUrl:webResourceItem.getAdditionalInfo().get("thumbnailURL") , contentUrl: DEFAULT_VIDEO_DOMAIN + contentUrl)
    }

    @Override
    boolean extractorMatches(URL url) {
        return url ==~ VALID_WEB_RESOURCE_URL
    }

    @Override
    String getExtractorName() {
        return getClass().getName()
    }
    static void main(args) {
        def TestUrl = new URL("http://www.ted.com/talks/cameron_russell_looks_aren_t_everything_believe_me_i_m_a_model.html;http://www.ted.com/talks/andy_puddicombe_all_it_takes_is_10_mindful_minutes.html")
        TED extractor = new TED()
        println "PluginName               : " + extractor.getExtractorName();
        println "TestMatch                : " + extractor.extractorMatches(TestUrl);
        WebResourceContainer container = extractor.extractItems(TestUrl, -1);
        container.getItems().each {
            println "URL                  : " + extractor.extractUrl(it, PreferredQuality.HIGH)
        }
    }
}
