import groovy.util.XmlParser
import groovy.json.JsonSlurper
import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*

/**
 * WebResource extractor plugin for beeg.com
 * 
 * @author jhb50
 * Version 1 - Nov. 10, 2012
 * Version 2 - Nov. 12, 2012 5x Performance improvement, tag,long and page support
 * Version 3 - Nov. 13, 2012 Eliminate repeat ffmpeg parsing since all videos are the same format
 * Version 4 - Nov. 30, 2012 For parameter now overrides console value for number of videos 
 * Version 5 - Dec. 14, 2012 Support New web source
 * Version 6 - Jan. 05, 2013 Major Performance improvement, Support site search & http://beeg.com url, add timestamps.
 * Version 7 - Jan. 05, 2013 Improved URL Extract Performance as well.
 * Version 8 - Jan. 06, 2013 Fix titles and thumb extract, add option to generate urls
 * Version 9 - Jan. 08, 2013 Eliminate genurls option and only extract when played.
 * Version 10 - Jan. 14, 2013 Add usegen option to ignore new beeg urls
 * Version 11 - May  27, 2013 Fix empty search bug, video/titles mismatch.
 */
class Beeg extends WebResourceUrlExtractor {
	long StartETime = 0
	long LastETime2 = 0
	long LastETime3 = 0
	Short genSw = 0
	
	final VALID_FEED_URL = '^(?:https?://)?(?:www\\.)?beeg\\.com.*+'
	
	String getExtractorName() {
		return 'Beeg'
	}
	
	int getVersion() {
		return 11
	}

	Long ETimer(String msg){
		long CurrentTime = System.currentTimeMillis()
		long Elapsed = CurrentTime - StartETime
		if (msg != null){
			log("$msg = $Elapsed msec")
		}
		return Elapsed
	}

	Long ETimer2(String msg){
		long CurrentTime = System.currentTimeMillis()
		long Elapsed = CurrentTime - LastETime2
		LastETime2 = CurrentTime
		if (msg != null){
			log("$msg = $Elapsed msec")
		}
		return Elapsed
	}
	
	Long ETimer3(String msg){
		long CurrentTime = System.currentTimeMillis()
		long Elapsed = CurrentTime - LastETime3
		LastETime3 = CurrentTime
		if (msg != null){
			log("$msg = $Elapsed msec")
		}
		return Elapsed
	}

	Boolean URLExists(URL fileURL){
		if(((HttpURLConnection) fileURL.openConnection()).getResponseCode() == 404){
			return false
		}
		return true
	}

	boolean extractorMatches(URL feedUrl) {
		return feedUrl ==~ VALID_FEED_URL
	}
	
	WebResourceContainer extractItems(URL resourceUrl, int maxItems) {
	
		log("Parsing with Beeg V${getVersion()}")

		StartETime = System.currentTimeMillis()
		ETimer2()
		ETimer3()

		List<WebResourceItem> items = []
		def itemsAdded = 0 
		String pageTitle = ""
		String pageThumb = ""
		String videoUrl = ""
		String videoTitle = ""
		String thumbUrl = ""
		Short Start = 0
		Short For = 10
		Boolean ForSet = false
				
		def parmMatcher = resourceUrl =~ '^http://(?:www\\.)?beeg\\.com.*?for=([0-9]+)'
		def parmMatch = resourceUrl ==~ '^http://(?:www\\.)?beeg\\.com.*?for=[0-9]+.*?'
		if (parmMatch){
			For = parmMatcher[0][1].trim().toShort() 
			ForSet = true
			if(For < 1) ForSet = false
		}

		parmMatcher = resourceUrl =~ '^http://(?:www\\.)?beeg\\.com.*?start=([0-9]+)'
		parmMatch = resourceUrl ==~ '^http://(?:www\\.)?beeg\\.com.*?start=[0-9]+.*?'
		if (parmMatch){
			Start = parmMatcher[0][1].trim().toShort() - 1
			if(Start < 0 )Start = 0
			if(Start > 399) Start = 399-For
		}

		parmMatcher = resourceUrl =~ '^http://(?:www\\.)?beeg\\.com.*?usegen=([0-1])'
		parmMatch = resourceUrl ==~ '^http://(?:www\\.)?beeg\\.com.*?usegen=[0-1].*?'
		if (parmMatch){
			genSw = parmMatcher[0][1].trim().toShort()
		}

		if (resourceUrl.toString().contains("?") && !resourceUrl.toString().contains("search?q=")){
			def rootMatcher = resourceUrl =~ '^(.*?)\\?.*?'
			resourceUrl= new URL(rootMatcher[0][1])
		}
		
		
		ETimer2("Startup")							
				
		def html = openURL(resourceUrl,"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1")
		ETimer2("Read URL")							

		def titleMatcher = html =~ '(?s)<meta name="Description" content=(.+?)/'
		pageTitle = titleMatcher[0][1].trim()
	    def idMatcher = html =~ '(?s)var tumbid  =\\[(.*?);'
	    def thumbMatcher = html =~ '(?s)var tumbalt =\\[(.*?);'

	    if (idMatcher.size() > 0) {
			def idMatch = idMatcher[0][1] =~ "(?s)(.*?)[,\\]]"
			println idMatch.size()
			if (idMatch.size() == 1) return
			def thumbMatch = thumbMatcher[0][1] =~ "(?s)'(.*?)'[,\\]]"

			def thumbURL = html =~ "(?s)var IMGthumb = '(.*?)/'"
			//def videoURL = html =~ "(?s)var URLthumb = '(.*?)'"
			def videoURL = "http://beeg.com/"
			if (ForSet) maxItems = For
			ETimer2("Parse Web Page")						
			
			int i
			for( i = Start; i < idMatch.size() && i < thumbMatch.size() && (maxItems == -1 || itemsAdded < maxItems); i++ ) {
				
				if (ETimer() > 29000){
					log ("Time Limit of 30 Seconds Reached") 
					break
				}
				
				def id = idMatch[i][1].trim()
				videoUrl = videoURL + id
				thumbUrl = thumbURL[0][1] + "-" + id + ".jpg"
				videoTitle = thumbMatch[i][1].trim()
				videoTitle = videoTitle.replaceAll("\\\\'", "'")
				String gen = "true"
								
				WebResourceItem item = new WebResourceItem(title: videoTitle, additionalInfo: ['id':id,'videoUrl':videoUrl,'thumbUrl':thumbUrl,'gen':gen])
				
				items << item
				itemsAdded++
			}
			ETimer2("Create " + itemsAdded + " Items")	
		}
		ETimer("Total Item Extract Time")
		return new WebResourceContainer(title: pageTitle, thumbnailUrl: pageThumb, items: items)
	}

	ContentURLContainer extractUrl(WebResourceItem item, PreferredQuality requestedQuality) {		
		
		String videoTitle = item.title
		String videoid = item.getAdditionalInfo()['id']
		String videoUrl = item.getAdditionalInfo()['videoUrl']
		String thumbnailUrl = item.getAdditionalInfo()['thumbUrl']
		String gen = item.getAdditionalInfo()['gen']
		String linkUrl
		String cacheKey
		
		List IPorts = ["0", "2", "4", "6", "8", "10", "12", "14", "16"]
       
		if (gen == "true"){
			Collections.shuffle(IPorts)
			linkUrl = "http://" + IPorts[0] + ".video.mystreamservice.com/480p/" + videoid + ".mp4"
			cacheKey = "beeg" + "480p"
			item.additionalInfo.put('gen',"false")
			log("Generating url : gen changed to false")
		}
		else{
			log("Extracting url")
			String videohtml = openURL(new URL(videoUrl),"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1")
		
			
		
			def javaMatch = videohtml ==~ "(?s).*?<div class=\"media-box\">.*?<div id=\"media\">.*?<script.type='text/javascript'.*?"
			if (!javaMatch){
				log("NO ENTRIES FOR THIS ITEM - \'$videoTitle\'")
				println "NO ENTRIES FOR THIS ITEM - \'$videoTitle\'"
				return null
			}

			def linkMatcher = videohtml =~ "(?s)'file'.*?'(.*?)'"
			linkUrl = linkMatcher[0][1]
			def typeMatcher = linkUrl =~ "http://.*?/(.*?)/"
			cacheKey = "beeg_" + videoid
		}
		
		if(genSw) 	
		return new ContentURLContainer(fileType: MediaFileType.VIDEO, contentUrl: linkUrl, thumbnailUrl: thumbnailUrl, cacheKey: cacheKey, expiresImmediately: false)
		else
		return new ContentURLContainer(fileType: MediaFileType.VIDEO, contentUrl: linkUrl, thumbnailUrl: thumbnailUrl, cacheKey: cacheKey, expiresImmediately: true)
	}
	
	static void main(args) {
		Beeg extractor = new Beeg()
				
		assert extractor.extractorMatches( new URL("http://www.beeg.com") )
		assert !extractor.extractorMatches( new URL("http://google.com/feeds/api/standardfeeds/top_rated?time=today") )
		//WebResourceContainer container = extractor.extractItems( new URL("http://www.beeg.com"), 10)    
		//WebResourceContainer container = extractor.extractItems( new URL("http://beeg.com?for=5"), -1)    
		WebResourceContainer container = extractor.extractItems( new URL("http://www.beeg.com/search?q=dumb"), 15)    
		//WebResourceContainer container = extractor.extractItems( new URL("http://www.beeg.com/tag/stupid/?start=1&for=1"), -1)    
		//WebResourceContainer container = extractor.extractItems( new URL("http://www.beeg.com/section/long-videos/2?start=1&for=5"), -1)    
		println container
		
		ContentURLContainer result = extractor.extractUrl(container.getItems()[0], PreferredQuality.MEDIUM)
		println result
	}
}
