import org.serviio.library.metadata.*
import org.serviio.library.online.*
import groovy.json.*

/**
 * YouTube.com content URL extractor plugin. 
 * 
 * Youtube API v3
 * Using youtube_dl with best quality
 *  
 * @author Stefan Andersson
 *
 **/

class YouTube extends WebResourceUrlExtractor {

    final MAX_ITEMS = 125  // Set number of items here to retrieve

    final VALID_RESOURCE_URL = '^https?://www.googleapis.com/youtube/.*$'
        
    String getExtractorName() {
        return getClass().getName()
    }
    
    boolean extractorMatches(URL feedUrl)
    {
        return feedUrl ==~ VALID_RESOURCE_URL
    }
    
    WebResourceContainer extractItems(URL resourceUrl, int maxItemsToRetrieve)     
    {
      final user_agent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)"
      final api_key = *** API KEY HERE ***

      if (resourceUrl.toString().contains("/channels?")) {
          def channelUrl = new URL(resourceUrl.toString() + "&part=contentDetails" + "&key=" + api_key)  
	  def channeljson = new JsonSlurper().parseText(openURL(channelUrl, user_agent))
	  def uploadPlaylist = channeljson.items[0].contentDetails.relatedPlaylists.uploads
			 
	  resourceUrl = new URL("https://www.googleapis.com/youtube/v3/playlistItems?playlistId=$uploadPlaylist")
      }	

      def done = 0
      def page = ""
      def items = []

      while (true)
      {
        def apiUrl = new URL(resourceUrl.toString() + "&part=snippet" + "&maxResults=50" + page + "&type=video" + "&key=" + api_key)

        def json = new JsonSlurper().parseText(openURL(apiUrl, user_agent))

        json.items.each()
        {
          if (it.snippet.title != "Deleted video" && it.snippet.title != "Private video")
          {
            items.add(new WebResourceItem(title : it.snippet.title,
                             additionalInfo : ['videoId' : resourceUrl.toString().contains("/videos?") ? it.id
                                                         : resourceUrl.toString().contains("/search?") ? it.id.videoId
                                                         : it.snippet.resourceId.videoId,
                                                 'thumb' : it.snippet.thumbnails.high.url]))

            log("title: ${it.snippet.title}")
            log("videoId: ${resourceUrl.toString().contains("/videos?") ? it.id : resourceUrl.toString().contains("/search?") ? it.id.videoId : it.snippet.resourceId.videoId}")
            log("thumb: ${it.snippet.thumbnails.high.url}")
          }
        }

        done += 50
        if (done >= MAX_ITEMS || done >= json.pageInfo.totalResults.toInteger()) break
        page = "&pageToken=" + json.nextPageToken
      }

      return new WebResourceContainer(title : "", items : items)
    }
      
    ContentURLContainer extractUrl(WebResourceItem item, PreferredQuality requestedQuality)
    {
      def linkUrl = "http://www.youtube.com/watch?v=${item.additionalInfo['videoId']}"
      def thumbnailUrl = item.additionalInfo['thumb']
	
      def command = /C:\Program Files\Serviio\lib\youtube-dl --proxy "" -g -f best $linkUrl/

      log("Executing $command")
 
      def proc = command.execute()
      proc.waitFor()

      if (proc.exitValue() == 0)
      {
        def contentUrl = proc.in.text.trim()

        return new ContentURLContainer(contentUrl : contentUrl, thumbnailUrl : thumbnailUrl, expiresImmediately : true, cacheKey : linkUrl )
        
      }
      else
      {
        log("${proc.err.text}")

         return null
      }          
    }
 }