import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*

/**
 * WebResource extractor plugin for video.ap.org
 *
 * @author jhb50
 *
 * Version 1 - Apr. 26, 2012
 * Version 2 - Feb.  4, 2013 - add Quick refresh
 * Version 3 - Feb.  5, 2013 - Support Quick Refresh for subsets.
 * Version 4 - Feb. 10, 2013 - update refresh logic
 * Version 5 - Apr. 11, 2013 - fix title special characters
 * 
 *
 * This plugin displays Associated Press videos
 *
 * URL http://video.ap.org displays "editors picks"
 * or
 * URL http://video.ap.org?feed=xxxxxx displays subsets
 * where xxxxxx are Video Playlist names from the left side of the url page.
 * Any blanks must be replaced with underscores _
 *  
 * Current playlists are:
 * Raw_Video
 * U._S.
 * World
 * Most_Watched
 * Showbiz
 * Sports
 * Politics
 * Offbeat
 * Sci-Tech
 * Today_in_History
 *
 */
class APVideo extends WebResourceUrlExtractor {
	
	List<WebResourceItem> newitems = []
	List<WebResourceItem> olditems = []

	final VALID_FEED_URL = '^(?:http?://)?(?:www\\.)?video\\.ap\\.org.*?'
	
	String getExtractorName() {
		return 'APVideo'
	}
	
	boolean extractorMatches(URL feedUrl) {
		return feedUrl ==~ VALID_FEED_URL
	}

	int getVersion() {
		return 5
	}
	
	WebResourceContainer extractItems(URL resourceUrl, int maxItems) {
	
		log("Parsing with APVideo V${getVersion()}")

		def genurls = 1
		def curDate = new Date(System.currentTimeMillis()+300000)
		olditems = []
		if (newitems){
			def newitemssize = newitems.size()
			def nli = newitems.iterator()
			while (nli.hasNext()){
				def newEntry = nli.next()
				if(newEntry.getAdditionalInfo()['XexpiresImmediately']!= true) continue
				def SavedExpiryDate = newEntry.getAdditionalInfo()['XexpiresOn']
				if(SavedExpiryDate > new Date(0) && curDate >= SavedExpiryDate) continue
				olditems << newEntry
			}
			def olditemssize = olditems.size()
			log ( olditemssize + " items saved, " + (newitemssize - olditemssize) +  " expired" )
			olditems = olditems.drop(olditemssize-300)
			newitems = olditems
		}

		List<WebResourceItem> items = []
		def itemsAdded = 0
		long Refreshi = 0
		long Refresha = 0
		def Refreshat

		def parmMatcher = resourceUrl =~ '^http://video\\.ap\\.org*?genurls=([0-1])'
		def parmMatch = resourceUrl ==~ '^http://video\\.ap\\.org.*?genurls=[0-1].*?'
		if (parmMatch){
		    genurls = parmMatcher[0][1].trim()  
		}
		parmMatcher = resourceUrl =~ '^http://video\\.ap\\.org.*?refresh=([0-9]+)'
		parmMatch = resourceUrl ==~ '^http://video\\.ap\\.org.*?refresh=[0-9]+.*?'
		if (parmMatch){
			Refreshi = parmMatcher[0][1].trim().toLong()
			long curTime=System.currentTimeMillis()/60000
			Refresha = (System.currentTimeMillis()/60000) + Refreshi + 5
		}

		String html = resourceUrl.getText()
		def freewheelMatcher = html =~ "(?s)freewheel = '(.*?)';"
		String freewheel = freewheelMatcher[0][1].trim()
		def widmatch = html =~ '(?s)wid.=."(.*?)";'
		String wid = widmatch[0][1]
		String pagesUrl = "http://ps2.newsinc.com//playlist/GetWidgetPlaylists/" + freewheel + "/" + wid + ".xml"
		String pages = new URL (pagesUrl).getText()
		def playlistMatcher = pages =~ '(?s)<Playlist>.*?<ID>(.*?)</ID>.*?<Name>AP.(.*?)</Name>.*?'

		String feed
		String feedName
		def feedNum
		String programID
		String programName
		String thumbUrl
		
		def feedMatcher = resourceUrl =~ '(?s).*?org\\?feed=(.*+)'
		def feedMatch = resourceUrl ==~ '(?s).*?org\\?feed=.*+'
		if (feedMatch){
		    feed = feedMatcher[0][1]
		}
		else feed = "Editors_Picks"	
		
		
		for( int i = 0; i < playlistMatcher.size(); i++) {
			feedName = playlistMatcher[i][2].trim().replaceAll(" ","_")
			if (feed.contains(feed)) {
				feedNum = playlistMatcher[i][1]
				break
			}
		}
		
		String pageTitle = feedName

		String feedUrl = "http://ps2.newsinc.com//Playlist/show/" + freewheel + "/" + wid + "/" + feedNum + ".xml"
		String links = new URL(feedUrl).getText()
		def linksMatcher = links =~ '(?s)<Program><ID>(.*?)</ID><Name>(.*?)</Name>.*?'
		
		for( int i = 0; i < linksMatcher.size(); i++) {
			programID = linksMatcher[i][1].trim()
			programName = linksMatcher[i][2].trim().replaceAll("&#39;","'").replaceAll("&amp;","&").replaceAll("&quot;",'"')
			
			def itemkey = "APVideo_" + programID

			WebResourceItem item = new WebResourceItem(title: programName, additionalInfo: ['itemkey':itemkey, 'programID':programID])

			item.additionalInfo.put('gen',"false")
			if(olditems && itemkey){
				for (int oij=olditems.size(); oij > 0; oij--){
					String olditem = olditems.getAt(oij-1).toString()
					if(olditem.contains(itemkey)){
						item.additionalInfo.put('oindx',oij-1)
						if (genurls) item.additionalInfo.put('gen',"true")
						break
					}
				}
			}

			items << item
			itemsAdded++
		}  

		if (Refreshi == 0){
			log ("Folder Refresh Set to Console Default")
			Refreshat = "Console Default time"
		}
		else{
			Refreshat = new Date(Refresha*60000).format("H:mm 'on' E M/dd/yyyy ").trim()
			log ("Folder Refresh Set to " + Refreshat )
		}
		
		if (itemsAdded == 0 || Refreshi != 0){
			programID = "http://lastitem"
			if (itemsAdded == 0) channel_image = "https://sites.google.com/site/serviiorss/noevents.jpg"
			else thumbUrl = "https://sites.google.com/site/serviiorss/nomoreitems.jpg"
			
			programName = "Next Refresh at $Refreshat"
			if (itemsAdded == 0) log ("ADDED 'NO EVENTS' - $programName")
			else log ("ADDED 'NO MORE ITEMS' - $programName")
			WebResourceItem item = new WebResourceItem(title: programName, 
				additionalInfo: ['programID':programID,'thumbnailUrl':thumbUrl ,'refresha':Refresha])

			item.additionalInfo.put('gen',"false")
			items << item
		}
		return new WebResourceContainer(title: pageTitle, items: items)
	}
	
	ContentURLContainer extractUrl(WebResourceItem item, PreferredQuality requestedQuality) {		
		String programID = item.getAdditionalInfo()['programID']
		assert programID != null
		String Refresha = item.getAdditionalInfo()['refresha']
		String thumbUrl = item.getAdditionalInfo()['thumbnailUrl']
		String contentUrl
		boolean live
		def cacheKey
		def expiresImmediately
		Date expiryDate 
		
		String gen = item.getAdditionalInfo()['gen']

		if(gen == "false"){
		
			if (programID.contains("http://lastitem")){
				if (Refresha) expiryDate = new Date(Refresha.toLong() * 60000)
				contentUrl = "rtsp://a1709.l1856953708.c18569.g.lm.akamaistream.net:554/D/1709/18569/v00/reflector:53708"
				def secCode = "abcdefghi"
				cacheKey = "http://lastitem_" + secCode
				expiresImmediately = false
				live = true
			}
			else{

				contentUrl = "http://video.newsinc.com/" + programID + ".flv"
				thumbUrl = "http://thumbnail.newsinc.com/" + programID + ".jpg"

				log("Extracted url: " + contentUrl)
		
			
				live = false
			
				cacheKey = "APVideo" + '_' + programID
			
				expiresImmediately = true
			
			}
	
			item.additionalInfo.put('XcontentUrl',contentUrl)
			item.additionalInfo.put('XthumbnailUrl',thumbUrl)
			item.additionalInfo.put('XexpiresOn',expiryDate)
			item.additionalInfo.put('XexpiresImmediately',expiresImmediately)
			item.additionalInfo.put('XcacheKey',cacheKey)
			item.additionalInfo.put('Xlive',live)
			def oindx = item.getAdditionalInfo()['oindx']
			if(oindx){
				newitems[oindx] = item
			}
			else {
				oindx = newitems.size()
				item.additionalInfo.put('oindx',oindx)
				newitems << item
			}
			
		}//END of non gen EXTRACT

		else{   //START OF gen GENERATE
			println "\r\ngenerate url"
			item.additionalInfo.put('gen',"false")
			def oindx = item.getAdditionalInfo()['oindx']
			contentUrl = olditems.getAt(oindx).getAdditionalInfo()['XcontentUrl']
			log ("Generated url: " + contentUrl)
			thumbUrl = olditems.getAt(oindx).getAdditionalInfo()['XthumbnailUrl']
			expiryDate = olditems.getAt(oindx).getAdditionalInfo()['XexpiresOn']
			expiresImmediately = olditems.getAt(oindx).getAdditionalInfo()['XexpiresImmediately']
			cacheKey = olditems.getAt(oindx).getAdditionalInfo()['XcacheKey']
			live = olditems.getAt(oindx).getAdditionalInfo()['Xlive']
		}
	
		return new ContentURLContainer(fileType: MediaFileType.VIDEO, contentUrl: contentUrl, thumbnailUrl: thumbUrl, live: live, expiresOn: expiryDate, cacheKey: cacheKey, expiresImmediately: expiresImmediately)
	}
	
	static void main(args) {
		// this is just to test
		APVideo extractor = new APVideo()
				
		assert extractor.extractorMatches( new URL("http://video.ap.org") )
		assert !extractor.extractorMatches( new URL("http://google.com/feeds/api/standardfeeds/top_rated?time=today") )
		
		WebResourceContainer container = extractor.extractItems( new URL("http://video.ap.org?refresh=30"), -1)
		//WebResourceContainer container = extractor.extractItems( new URL("http://video.ap.org?feed=U._S."), -1)
		//println container
		
		container.getItems().each {																					 
		ContentURLContainer result = extractor.extractUrl(it, PreferredQuality.MEDIUM)							 
		println result 														
		}		

		WebResourceContainer container2 = extractor.extractItems( new URL("http://video.ap.org?refresh=30"), -1)
		//WebResourceContainer container2 = extractor.extractItems( new URL("http://video.ap.org?feed=U._S."), -1)
		//println container2
		
		container2.getItems().each {																					 
		ContentURLContainer result2 = extractor.extractUrl(it, PreferredQuality.MEDIUM)							 
		println result2 														
		}
		
		WebResourceContainer container3 = extractor.extractItems( new URL("http://video.ap.org?refresh=30"), -1)
		//WebResourceContainer container3 = extractor.extractItems( new URL("http://video.ap.org?feed=U._S."), -1)
		//println container3
		
		container3.getItems().each {																					 
		ContentURLContainer result3 = extractor.extractUrl(it, PreferredQuality.MEDIUM)							 
		println result3 														
		}
	}
}
