
import groovy.json.JsonSlurper
import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*
import static java.util.Calendar.*

/********************************************************************
 * desirulez plugin for Serviio
 *
 * @author Mandar Hawaldar
 *
 * URL to use as video webresource: http://www.desirulez.net/forumdisplay.php?f=2146
 * URL to use as video webresource: http://www.desirulez.net/showthread.php?t=608320
 *
 * Version:
 *    V1.0: - Feb 14, 2014
 *
 ********************************************************************/
 
 class desirulez extends WebResourceUrlExtractor {
 
	final VALID_RESOURCE_URL = '(.*?)www.desirulez.net(.*?)'
	final TITLE = 'DesiRulez'
	final BASE_URL = ''

	final MOVIE_PAGE_EXTRACTOR = '<div class="video-object-thumb"><a href="..(.*?)"'
	final CHANNEL_LINK_EXTRACTOR = "'hd-2': (.*?) 'file': '(.*?)'"
	final THUMB_LINK_EXTRACTOR = 'class="movie-cover-wrapper"(.*?)src="(.*?)"'
	final CHANNEL_TITLE_EXTRACTOR = "<title>(.*?) Movie Online HD DVD</title>"
	final MY_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.1'
    Date dExpiresOn
	
	String getExtractorName() {
		return 'desirulez.groovy'
	}
	
	boolean extractorMatches(URL resourceURL) {
		def urlval = resourceURL.toString() =~ VALID_RESOURCE_URL
		log(String.format("extractorMatches %s - %d", resourceURL.toString(), urlval.count))
                if (urlval.count > 0)
		{
		    return true
		}
		else
		{
			return false
		}
	}
   
	/**/
	void write_to_log(
		String text
	) {
		log(TITLE + ' - ' + text)
	}
	/**/
	public int getVersion() {
		return 1.0
	}
	Boolean URLExists(URL fileURL){
		if(((HttpURLConnection) fileURL.openConnection()).getResponseCode() == 404){
			return false
		}
		return true
	}
	
	
	WebResourceContainer extractItems(URL resourceURL, int maxItemsToRetrieve) {
	
		List<WebResourceItem> items = []
		write_to_log(String.format("extractItems - %s", resourceURL))
		def itemsCount = 0
		def sOnAirTime = "8:30"
		
		if (URLExists(resourceURL) == false) {
			write_to_log("Invalid Resource URL")
			return null
		}
		
		write_to_log(String.format("extractItems: B4 openURL [%s]", resourceURL.toString()))
		def resourceText = openURL(resourceURL, MY_USER_AGENT)
		write_to_log(String.format("extractItems: AFTER openURL [%s]", resourceURL.toString()))
		def onAirtimeMatcher = resourceText =~ /(?i).* to .* at (.* [ap].m.) .* time/
		if(onAirtimeMatcher.count > 0){
			write_to_log("extractItems: On Air Time : ${onAirtimeMatcher[0][1]}")
			sOnAirTime = onAirtimeMatcher[0][1]
		}
		dExpiresOn = calculateExpTime(sOnAirTime)
		write_to_log(String.format("extractItems: Expires On [%s]", dExpiresOn))

		//def threadUrlMatcher = resourceText =~ /<a .*href="([^"]*Watch-Online[^"]*)".*>.*Watch Online.*<\/a>/
		def threadUrlMatcher = resourceText =~ /<a class.*href="([^"]*Watch-Online[^"]*)".*>.*Watch Online.*<\/a>/
		def threadUrlCount = threadUrlMatcher.count
		write_to_log(String.format("extractItems Found #%d thread URLs", threadUrlCount))
		if (threadUrlCount > 5){
			threadUrlCount = 5
		}
		for (threadUrlIndex in 1..threadUrlCount)
		{
			write_to_log(String.format("extractItems Thread # %d - [http://www.desirulez.net/%s]", threadUrlIndex,
						threadUrlMatcher[threadUrlIndex-1][1]))

			def threadURL = ("http://www.desirulez.net/" + threadUrlMatcher[threadUrlIndex-1][1]).toURL()
			write_to_log(String.format("extractItems: B4 openURL [%s]", threadURL))
			def threadText = openURL(threadURL, MY_USER_AGENT)
			write_to_log(String.format("extractItems: AFTER openURL [%s]", threadURL))

			def VTUrlMatcher 
			def VTUrlCount = 0

			//def VTUrlBlockMatcher = threadText =~ /(?ms)<b><font[^>]*>(Video Tanker|Videotanker) (?:720p )*HD Quality Online Links<\/font><\/b><br\/>\n<br\/>\n(.*?)<br\/>\n<br\/>\n/
			//def VTUrlBlockMatcher = threadText =~ /(?ms)<b><font[^>]*>(Video Tanker|Videotanker) (?:720p )*(?:HD|DVD) Quality Online Links<\/font><\/b><br *\/>\n<br *\/>\n(.*?)<br *\/>\n<br *\/>\n/
			def VTUrlBlockMatcher = threadText =~ /(?ms)<b><font[^>]*>(Video Tanker|Videotanker) (?:720p )*(?:HD|DVD) Quality Online Links<\/font><\/b><br *\/>(?:\r)*\n<br *\/>(?:\r)*\n(.*?)<br *\/>(?:\r)*\n<br *\/>(?:\r)*\n/
			if (VTUrlBlockMatcher.count > 0){
				VTUrlMatcher = VTUrlBlockMatcher[0][2] =~ /<a href=".*=(.*?)" .*>(.*?)<\/a>/
				VTUrlCount = VTUrlMatcher.count
				write_to_log(String.format("extractItems: Found #%d Videotanker URLs", VTUrlCount))
			}

			if (VTUrlCount > 0){
			for (VTUrlIndex in 1..VTUrlCount)
			{
				def VideotankerURL = ("http://videotanker.co/player/embed_player.php?vid=" + VTUrlMatcher[VTUrlIndex-1][1]).toURL()
				def videoTitle = (VTUrlMatcher[VTUrlIndex-1][2]).replaceAll(' Watch Online', '')
				write_to_log(String.format("extractItems: Adding # %d - [%s][%s]",
							VTUrlIndex, videoTitle, VideotankerURL.toString()))

				items << new WebResourceItem(
								title: videoTitle,
								additionalInfo: [
								channelURL: VideotankerURL,
								videoPageURL: VideotankerURL,
								videoPageHost: 'VIDEOTANKER',
								expiresOn : dExpiresOn,
								cacheKey: TITLE + ' ' + videoTitle
								])
				itemsCount++
				if (itemsCount >= maxItemsToRetrieve){
					write_to_log(String.format("extractItems: Returning items.size()=[%d] itemsCount[%d]\n",
								items.size(), itemsCount))
					return new WebResourceContainer(title: TITLE, items: items)
				}
			}
			}
            else{ // Try DailyMotion
				def DMUrlMatcher 
				def DMUrlCount = 0
				//def DMUrlBlockMatcher = threadText =~ /(?ms)<b><font[^>]*>(Dailymotion) (?:720p )*HD Quality Online Links<\/font><\/b><br\/>\n<br\/>\n(.*?)<br\/>\n<br\/>\n/
				//def DMUrlBlockMatcher = threadText =~ /(?ms)<b><font[^>]*>(Dailymotion) (?:720p )*HD Quality Online Links<\/font><\/b><br *\/>\n<br *\/>\n(.*?)<br *\/>\n<br *\/>\n/
				def DMUrlBlockMatcher = threadText =~ /(?ms)<b><font[^>]*>(Dailymotion) (?:720p )*HD Quality Online Links<\/font><\/b><br *\/>(?:\r)*\n<br *\/>(?:\r)*\n(.*?)<br *\/>(?:\r)*\n<br *\/>(?:\r)*\n/
				if (DMUrlBlockMatcher.count > 0){
					DMUrlMatcher = DMUrlBlockMatcher[0][2] =~ /<a href=".*=(.*?)" .*>(.*?)<\/a>/
					DMUrlCount = DMUrlMatcher.count
					write_to_log(String.format("extractItems: Found #%d DailyMotion URLs", DMUrlCount))
					}
				if (DMUrlCount > 0){
					for (DMUrlIndex in 1..DMUrlCount)
					{
						def DailymotionURL = ('http://www.dailymotion.com/video/' + DMUrlMatcher[DMUrlIndex-1][1]).toURL()
						def videoTitle = (DMUrlMatcher[DMUrlIndex-1][2]).replaceAll(' Watch Online', '')
						def videoId = DMUrlMatcher[DMUrlIndex-1][1]
						write_to_log(String.format("extractItems: Adding # %d - [%s][%s]",
									DMUrlIndex, videoTitle, DailymotionURL.toString()))
		
						items << new WebResourceItem(
								title: videoTitle,
								additionalInfo: [
								channelURL: DailymotionURL,
								videoPageURL: DailymotionURL,
								videoPageHost: 'DAILYMOTION',
								expiresOn : dExpiresOn,
								videoId: videoId,
								cacheKey: TITLE + ' ' + videoTitle
								])
						itemsCount++
						if (itemsCount >= 10){
							write_to_log(String.format("extractItems: Returning items.size()=[%d] itemsCount[%d]\n",
									items.size(), itemsCount))
							return new WebResourceContainer(title: TITLE, items: items)
						}
					}
				}
			}
		}

		write_to_log(String.format("extractItems Returning items.size()=[%d] itemsCount[%d]\n", items.size(), itemsCount))
					
		return new WebResourceContainer(title: TITLE, items: items)
	}
	
	protected ContentURLContainer extractUrl(WebResourceItem webResourceItem, PreferredQuality preferredQuality) {
		write_to_log(String.format("extractUrl: channelURL=[%s]",
					webResourceItem.getAdditionalInfo().get("channelURL")))
		write_to_log(String.format("extractUrl: videoPageHost [%s]",
						webResourceItem.getAdditionalInfo().get("videoPageHost")))
		if(log.isDebugEnabled()){
			log(String.format("Staring video URL extraction for [%s]",
						webResourceItem.getAdditionalInfo().get("videoPageURL")))
		}
		try{
			if (webResourceItem.getAdditionalInfo().get("videoPageHost").equals("VIDEOTANKER")){
				def videotanker = new Videotanker()

				return videotanker.extractUrl(webResourceItem, preferredQuality)
			}
			else if (webResourceItem.getAdditionalInfo().get("videoPageHost").equals("DAILYMOTION")){
				def dailymotion = new Dailymotion()

				return dailymotion.extractUrl(webResourceItem, preferredQuality)
			}
		}catch (IndexOutOfBoundsException e){
			log.error(String.format("%s , Filed to create resource item for URL: %s",getExtractorName(), webResourceItem.getAdditionalInfo().get("videoPageURL")), log.isDebugEnabled()? e:null)
		}
		return null
	}

	def String findSuitableQuality(List items, PreferredQuality requestedQuality) {
		log(String.format("findSuitableQuality: requestedQuality[%s]\n", requestedQuality.toString()))
		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()
		}
	}

	def Date calculateExpTime(String onAirTime){
			def onAirHH = 22
			def onAirMM = 30
			def airTimeMatcher = onAirTime =~ /(\d*):(\d*)/
			//println(String.format("calculateExpTime airTimeMatcher count # %d", airTimeMatcher.count))
			if (airTimeMatcher.count>0){
				onAirHH = Integer.parseInt(airTimeMatcher[0][1]) + 3
				onAirMM = Integer.parseInt(airTimeMatcher[0][2])
			}
			if (onAirTime.contains("p.m.")){
				onAirHH += 12
			}
			//println 'onAir = ' + onAirHH + ':' + onAirMM

			def todayCal = Calendar.getInstance(TimeZone.getTimeZone("IST"))
			//todayCal.set 2014, JANUARY, 12
			//todayCal.set(year: 2014, month: JANUARY, date: 12, hourOfDay: 11, minute: 30, second: 00)
			//println todayCal.time

			def dateFormat = 'yyyy/MM/dd HH:mm z'
			def todayDate = todayCal.time
			//println todayDate.format(dateFormat, TimeZone.getTimeZone("EST"))
			//println todayDate.format(dateFormat, TimeZone.getTimeZone("IST"))
			def currHH = todayDate.format('HH', TimeZone.getTimeZone("IST"))
			def currMM = todayDate.format('mm', TimeZone.getTimeZone("IST"))
			//println 'currHH = ' + Integer.parseInt(currHH)
			//println 'currMM = ' + Integer.parseInt(currMM)
			if (Integer.parseInt(currHH) > onAirHH ||
							(Integer.parseInt(currHH) == onAirHH && Integer.parseInt(currMM) > onAirMM)){
				//   set tomo date-10pm
				//println 'currHH > ' + onAirHH + ':' onAirMM
				todayCal.set(hourOfDay: onAirHH, minute: onAirMM, second: 00)
				//println todayCal.time
				todayDate = todayCal.time + 1
				//println todayDate
			}
			else{
				//   set today's date-10pm
				todayCal.set(hourOfDay: onAirHH, minute: onAirMM)
				todayDate = todayCal.time
			}
			//println todayDate.format(dateFormat, TimeZone.getTimeZone("EST"))
			//println todayDate.format(dateFormat, TimeZone.getTimeZone("IST"))
			return todayDate
	}

	static void main(args) {

		def extractor = new desirulez()
		def WebResourceContainer container 

        println extractor.calculateExpTime("8:00 p.m.")
        println extractor.calculateExpTime("8:00 a.m.")
		//container = extractor.extractItems( new URL("http://www.desirulez.net/forums/771-Crime-Patrol-Season-4"), 5)
		//container = extractor.extractItems( new URL("http://www.desirulez.net/forums/2305-Koffee-With-Karan-(Season-4-Star-World)"), 5)
		container = extractor.extractItems( new URL("http://www.desirulez.net/forums/2022-Mahabharat"), 50)
		//container = extractor.extractItems( new URL("http://www.desirulez.net/forums/256-Taarak-Mehta-Ka-Ooltah-Chashmah"), 5)
		//container = extractor.extractItems( new URL("http://www.desirulez.net/forums/1376-Devon-Ke-Dev-Mahadev"), 5)
		//container = extractor.extractItems( new URL("http://www.desirulez.net/forums/117-C-I-D"), 15)
		//container = extractor.extractItems( new URL("http://www.desirulez.net/forums/1004-Adaalat"), 5)
		
		/**/
		container.getItems().each {
			ContentURLContainer result = extractor.extractUrl(it, PreferredQuality.HIGH)
			println result
		}
	   /**/
	}
 }
