import groovy.json.JsonSlurper
import org.serviio.library.metadata.*
import org.serviio.library.online.*
import org.serviio.util.*
import static java.util.Calendar.*

/********************************************************************
 * Dailymotion plugin for Serviio
 *
 * @author Mandar Hawaldar
 *
 * URL to use as video webresource: http://videotanker.co/player/embed_player.php?vid==ix8jh6mvfh1ih
 *
 * Version:
 *    V1.0: - Jan 21, 2014
 *
 ********************************************************************/
 
 class Dailymotion extends WebResourceUrlExtractor {
 
	final VALID_RESOURCE_URL = 'http://.*dailymotion.(?:co|com)/video/'
	final VID_EXTRACTOR = '^.+/video/([^_/]+)_?([^/]+)?$'
	final TITLE = 'Dailymotion'
	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'

	String getExtractorName() {
		return 'Dailymotion.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 videoTitle
		
		if (URLExists(resourceURL) == false) {
			write_to_log("Invalid Resource URL")
			return null
		}

		items << new WebResourceItem(
						title: videoTitle,
						additionalInfo: [
						    channelURL: resourceURL,
						    cacheKey: TITLE + ' ' + videoTitle
						])
		write_to_log(String.format("extractItems Returning items.size()=[%d] \n", items.size()))

		return new WebResourceContainer(title: TITLE, items: items)
	}

	protected String getMediaId(String resourceURL) {
        def mediaID
		def vidMatcher = resourceURL =~ VID_EXTRACTOR
		def vidCount = vidMatcher.count
		write_to_log(String.format("getMediaId Found #%d VIDEO IDs", vidCount))
		if (vidCount > 0){
			mediaID = vidMatcher[0][1]
			write_to_log(String.format("getMediaId mediaID=[%s]", mediaID))
		}
		return mediaID
	}

	protected String getMediaId(URL resourceURL) {
			return getMediaId(resourceURL.toString())
	}

	protected ContentURLContainer extractUrl(WebResourceItem webResourceItem, PreferredQuality preferredQuality) {
		write_to_log(String.format("extractUrl: channelURL=[%s]",
					webResourceItem.getAdditionalInfo().get("channelURL")))
		if(log.isDebugEnabled()){
			log(String.format("Staring video URL extraction for [%s]",
						webResourceItem.getAdditionalInfo().get("videoPageURL")))
		}
		try{
			def embdVidUrlMatcher
			def embedFileKey
			def mediaUrl
			def channelUrl = webResourceItem.getAdditionalInfo().get("channelURL")
			write_to_log(String.format("extractUrl: channelUrl=[%s]\n", channelUrl))
			def mediaID
			def webUrl
			def embedUrlList = []

			mediaID = getMediaId(channelUrl)
			if (mediaID != null){
				webUrl = 'http://www.dailymotion.com/embed/video/' + mediaID
				write_to_log(String.format("extractUrl: webUrl=[%s]", webUrl))

			}

			String embedPageHtml = webUrl.toURL().getText(
						requestProperties: ['User-Agent': MY_USER_AGENT]
						)

			embdVidUrlMatcher = embedPageHtml =~ '"stream_h264_ld_url":"(.*?)",'
			if (embdVidUrlMatcher.count > 0 && !embdVidUrlMatcher[0][1].equals("null")){
				mediaUrl = URLDecoder.decode(embdVidUrlMatcher[0][1].replaceAll('\\\\/', '/'),'UTF-8')
				write_to_log(String.format("extractUrl: stream_h264_ld_url mediaUrl=[%s]\n", mediaUrl))
				embedUrlList.add(mediaUrl);
			}

			embdVidUrlMatcher = embedPageHtml =~ '"stream_h264_url":"(.*?)",'
			if (embdVidUrlMatcher.count > 0 && !embdVidUrlMatcher[0][1].equals("null")){
				mediaUrl = URLDecoder.decode(embdVidUrlMatcher[0][1].replaceAll('\\\\/', '/'),'UTF-8')
				write_to_log(String.format("extractUrl: stream_h264_url mediaUrl=[%s]\n", mediaUrl))
				embedUrlList.add(mediaUrl);
			}

			embdVidUrlMatcher = embedPageHtml =~ '"stream_h264_hq_url":"(.*?)",'
			if (embdVidUrlMatcher.count > 0 && !embdVidUrlMatcher[0][1].equals("null")){
				mediaUrl = URLDecoder.decode(embdVidUrlMatcher[0][1].replaceAll('\\\\/', '/'),'UTF-8')
				write_to_log(String.format("extractUrl: stream_h264_hq_url mediaUrl=[%s]\n", mediaUrl))
				embedUrlList.add(mediaUrl);
			}

			embdVidUrlMatcher = embedPageHtml =~ '"stream_h264_hd_url":"(.*?)",'
			if (embdVidUrlMatcher.count > 0 && !embdVidUrlMatcher[0][1].equals("null")){
				mediaUrl = URLDecoder.decode(embdVidUrlMatcher[0][1].replaceAll('\\\\/', '/'),'UTF-8')
				write_to_log(String.format("extractUrl: stream_h264_hd_url mediaUrl=[%s]\n", mediaUrl))
				embedUrlList.add(mediaUrl);
			}

			def embdThumbUrlMatcher = embedPageHtml =~ '"thumbnail_url":"(.*?)",'
			def thumbnailUrl
			if (embdThumbUrlMatcher.count > 0 && !embdThumbUrlMatcher[0][1].equals("null")){
				thumbnailUrl = URLDecoder.decode(embdThumbUrlMatcher[0][1].replaceAll('\\\\/', '/'),'UTF-8')
				write_to_log(String.format("extractUrl: thumbnail_url embedThumbUrl=[%s]\n", thumbnailUrl))
			}

			webResourceItem.setTitle(webResourceItem.getTitle() + ' ' + TITLE)
			return new ContentURLContainer(
				contentUrl: URLDecoder.decode(findSuitableQuality(embedUrlList, preferredQuality),'UTF-8'),
				//thumbnailUrl: webResourceItem.getAdditionalInfo().get("thumbnailURL"),
				thumbnailUrl: thumbnailUrl,
				//expiresOn: cal.time,
				expiresOn: webResourceItem.getAdditionalInfo().get("expiresOn"),
				expiresImmediately: false,
				cacheKey : webResourceItem.getAdditionalInfo().get("cacheKey") + ' ' + TITLE,
				live: false
				)
		}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*)/
			log(String.format("calculateExpTime airTimeMatcher count # %d", airTimeMatcher.count))
			if (airTimeMatcher.count>0){
				onAirHH = Integer.parseInt(airTimeMatcher[0][1]) + 12 + 2
				onAirMM = Integer.parseInt(airTimeMatcher[0][2])
			}
			//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 Dailymotion()
		def WebResourceContainer container 

        println extractor.calculateExpTime("8:30")
		container = extractor.extractItems( new URL("http://www.dailymotion.com/video/x1ab2pc"), 5)
		//container = extractor.extractItems( new URL("http://www.divxstage.eu/video/ix8jh6mvfh1ih"), 5)
		
		/**/
		container.getItems().each {
			ContentURLContainer result = extractor.extractUrl(it, PreferredQuality.HIGH)
			println result
		}
	   /**/
	}
 }
