#!/usr/bin/python
# -*- coding: utf-8 -*-
import common
import connection
import m3u8
import os
import ustvpaths
import re
import simplejson
import sys
import time
import urllib
import xbmc
import xbmcaddon
import xbmcgui
import xbmcplugin
from bs4 import BeautifulSoup, SoupStrainer

addon = xbmcaddon.Addon()
player = common.XBMCPlayer()
pluginHandle = int(sys.argv[1])

SHOWS = 'http://api.watchabc.go.com/vp2/ws/s/contents/2015/shows/jsonp/%s/001/-1'
VIDEOLIST = 'http://api.watchabc.go.com/vp2/ws/s/contents/2015/videos/jsonp/%s/'
VIDEOURL = 'http://api.watchabc.go.com/vp2/ws/s/contents/2015/videos/jsonp/%s'
PLAYLISTMOV = 'http://www.kaltura.com/p/%s/sp/%s00/playManifest/format/rtmp/entryId/'
PLAYLISTMP4 = 'http://www.kaltura.com/p/%s/sp/%s00/playManifest/format/applehttp/entryId/'
PLAYLISTM3U = 'http://cdnapi.kaltura.com/p/%s/sp/%s00/playManifest/format/url/protocol/http/entryId/'
CLOSEDCAPTIONHOST = 'http://cdn.video.abc.com'
GETAUTHORIZATION = 'http://api.watchabc.go.com/vp2/ws-secure/entitlement/2015/authorize/json'
SWFURL = 'http://livepassdl.conviva.com/ver/2.61.0.65970/LivePassModuleMain.swf'
BITRATETABLE = {	60 : 'a',
					110 : 'b',
					190 : 'c',
					360 : 'd',
					590 : 'e',
					1010 : 'f',
					2100 : 'g',
					4800 : 'h',
					8000 : 'i'}

def masterlist(SITE, BRANDID):
	master_db = []
	master_data = connection.getURL(SHOWS % BRANDID)
	master_menu = simplejson.loads(master_data)['shows']['show']
	for master_item in master_menu:
		print master_item
		fullepisodes = 0
		clips = 0
		try:
			plot = master_item['description']
		except:
			plot = None
		if (int(master_item['clips']['count']['@total']) + int(master_item['fullepisodes']['count']['@total'])) > 0:
			if int(master_item['clips']['count']['@total']) > 0:
				try:
					if int(master_item['clips']['count']['video']['@accesslevel']) == 0:
						clips = int(master_item['clips']['count']['video']['$'])	
				except:
					if int(master_item['clips']['count']['video'][0]['@accesslevel']) == 0:
						clips = int(master_item['clips']['count']['video'][0]['$'])
			if int(master_item['fullepisodes']['count']['@total']) > 0:
				try:
					if int(master_item['fullepisodes']['count']['video']['@accesslevel']) == 0:
						fullepisodes = int(master_item['fullepisodes']['count']['video']['$'])
				except:
					if int(master_item['fullepisodes']['count']['video'][0]['@accesslevel']) == 0:
						fullepisodes = int(master_item['fullepisodes']['count']['video'][0]['$'])
			if fullepisodes > 0 or (clips > 0 and addon.getSetting('hide_clip_only') == 'false'):
				master_name = master_item['title'].strip()
				print master_name
				season_url = master_item['@id']
				print season_url
				try:
					thumb = master_item['thumbnails']['thumbnail']['$']
				except:
					thumb = None
				try:
					genre = master_item['genre'].title()
				except:
					genre = 'Special'
				if genre == 'Movies':
					master_name = '--' + master_name
					mode = 'episodes'
					season_url = VIDEOLIST % BRANDID + '001/lf/' + season_url + '/-1/-1/-1/-1'
				else:
					mode = 'seasons'
				site_data = {'plot' : plot,
							'thumb' : thumb,
							'genre' : genre}
				if 'Long Form' not in genre:
					print master_name, SITE, mode, season_url, site_data
					master_db.append((master_name, SITE, mode, season_url, site_data))
	return master_db

def seasons(SITE, BRANDID, season_url = common.args.url):
	seasons = []
	season_menu = []
	season_numbers = []
	clip_numbers = []
	try:
		season_url2 = VIDEOLIST % BRANDID + '001/-1/' + season_url + '/-1/-1/-1/-1'
		season_data = connection.getURL(season_url2)
		season_data2 = simplejson.loads(season_data)['videos']
		season_count = int(season_data2['@count'])
		if season_count > 1:
			season_menu = season_data2['video']
		elif season_count == 1:
			season_menu.append(dict(season_data2['video']))
		for season_item in season_menu:
			if int(season_item['@accesslevel']) == 0:
				if season_item['@type'] == 'lf':
					try:
						if season_item['season']['@id'] not in season_numbers:
							season_numbers.append(season_item['season']['@id'])
							season_name = 'Season ' + season_item['season']['@id']
							season_url3 = VIDEOLIST % BRANDID + '001/' + season_item['@type'] + '/' + season_url + '/' + season_item['season']['@id'] + '/-1/-1/-1'
							seasons.append((season_name, SITE, 'episodes', season_url3, -1, -1))
					except:
						pass
				elif season_item['@type'] == 'sf':
					try:
						if season_item['season']['@id'] not in clip_numbers:
							clip_numbers.append(season_item['season']['@id'])
							season_name = 'Season Clips ' + season_item['season']['@id']
							season_url4 = VIDEOLIST % BRANDID + '001/' + season_item['@type'] + '/' + season_url + '/' + season_item['season']['@id'] + '/-1/-1/-1'
							seasons.append((season_name, SITE, 'episodes', season_url4, -1, -1))
					except:
						pass
				else:
					print str(SITE) + ": new season type"
	except Exception as e:
		print "Error: " + e
	return seasons

def episodes(SITE, episode_url = common.args.url):
	episodes = []
	episode_menu = []
	episode_data = connection.getURL(episode_url)
	episode_data2 = simplejson.loads(episode_data)['videos']
	episode_count = int(episode_data2['@count'])
	if episode_count > 1:
		episode_menu = episode_data2['video']
	elif episode_count == 1:
		episode_menu.append(dict(episode_data2['video']))
	for episode_item in episode_menu:
		if int(episode_item['@accesslevel']) == 0:
			highest_height = -1
			episode_name = episode_item['title']
			episode_duration = int(episode_item['duration']['$']) / 1000
			episode_id = episode_item['@id']
			episode_type = episode_item['@type']
			try:
				episode_description = common.replace_signs(episode_item['longdescription'])
			except:
				try:
					episode_description = common.replace_signs(episode_item['description'])
				except:
					episode_description = None
			try:
				episode_expires = episode_item['availabilities']['free']['end']
			except:
				episode_expires = None
			try:
				episode_genre = episode_item['show']['trackcode']['generic']['cgenre'].title()
			except:
				episode_genre = None
			try:
				episode_airdate = episode_item['airdates']['airdate'].rsplit(' ',1)[0]
				episode_airdate = common.format_date(episode_airdate,'%a, %d %b %Y %H:%M:%S', '%d.%m.%Y')
			except:
				try:
					episode_airdate = episode_item['airdates']['airdate'][0].rsplit(' ',1)[0]
					episode_airdate = common.format_date(episode_airdate,'%a, %d %b %Y %H:%M:%S', '%d.%m.%Y')
				except:
					episode_airdate = -1
			if episode_genre != 'Movies':
				season_number = episode_item['season']['@id']
				try:
					episode_number = episode_item['number']
				except:
					episode_number = -1
				try:
					episode_number = re.compile('Episode (\d+)').findall(episode_name)[0]
				except:
					pass
			else:
				episode_number = -1
				season_number = -1
			try:
				for episode_picture in episode_item['thumbnails']['thumbnail']:
					try:
						picture_height = int(episode_picture['@width'])
					except:
						if episode_picture['@type'] == 'source-16x9':
							picture_height = 720
						else:
							picture_height = 0
					if picture_height > highest_height:
						highest_height = picture_height
						episode_thumb = episode_picture['$']
			except:
				episode_thumb = episode_item['thumbnails']['thumbnail']['$']
			if episode_genre == 'Movies':
				type = 'Movie'
			elif episode_type == 'lf':
				type = 'Full Episode'
			else:
				type = 'Clip'
			show_name = episode_item['show']['title']
			try:
				episode_mpaa = episode_item['tvrating']['rating'] + ' ' + episode_item['tvrating']['descriptors']
			except:
				try:
					episode_mpaa = episode_item['tvrating']['rating']
				except:
					episode_mpaa = None
			u = sys.argv[0]
			u += '?url="' + urllib.quote_plus(episode_id) + '#' + urllib.quote_plus(episode_type) + '"'
			u += '&mode="' + SITE + '"'
			u += '&sitemode="play_video"'
			infoLabels={'title' 		    : episode_name,
						'plot' 				: episode_description,
						'premiered' 		: episode_airdate,
						'durationinseconds' : episode_duration,
						'episode' 			: episode_number,
						'season' 			: season_number,
						'TVShowTitle' 		: show_name,
						'mpaa' 				: episode_mpaa,
						'genre' 			: episode_genre}
			infoLabels = common.enrich_infolabels(infoLabels, episode_expires.rsplit(' ',1)[0], '%a, %d %b %Y %H:%M:%S')
			episodes.append((u, episode_name, episode_thumb, infoLabels, 'list_qualities',False, type))
	return episodes
	
def list_qualities(SITE, BRANDID, PARTNERID):
	video_id, video_type = common.args.url.split('#')
	bitrates = []
	video_auth = get_authorization(BRANDID, video_id, video_type)
	if video_auth is False:
		video_url = VIDEOLIST % BRANDID + '001/-1/-1/-1/' + video_id + '/-1/-1'
		video_data = connection.getURL(video_url)
		try:
			video_data2 = simplejson.loads(video_data)['videos']['video']
			video_format = video_data2['assets']['asset'][0]['@format']
		except:
			try:
				video_data2 = simplejson.loads(video_data)['videos']['video']
				video_format = video_data2['assets']['asset']['@format']
			except:
				video_format = 'MOV'
		video_id = video_id.replace('VDKA','')
		if video_format == 'MP4':
			video_url = PLAYLISTMP4 % (PARTNERID, PARTNERID) + video_id
			video_data = connection.getURL(video_url)
			video_url2 = m3u8.parse(video_data)
			for video_index in video_url2.get('playlists'):
				bitrate = int(video_index.get('stream_info')['bandwidth'])
				bitrate.append((bitrate / 1000, bitrate))
		elif  video_format == 'MOV':
			video_url = PLAYLISTMOV % (PARTNERID, PARTNERID) + video_id
			video_data = connection.getURL(video_url)
			video_tree = BeautifulSoup(video_data, 'html.parser')
			base_url = video_tree('baseurl')[0].string
			video_url2 = video_tree.findAll('media')
			for video_index in video_url2:
				bitrate = int(video_index['bitrate'])
				bitrates.append((bitrate, bitrate))
	else:
		video_url = VIDEOLIST % BRANDID + '002/-1/-1/-1/' + video_id + '/-1/-1'
		video_data = connection.getURL(video_url)
		video_data2 = simplejson.loads(video_data)['videos']['video']
		video_closedcaption = video_data2['closedcaption']['@enabled']
		try:
			video_url2 = video_data2['assets']['asset']['$'] + video_auth
		except:
			video_url2 = video_data2['assets']['asset'][1]['$'] + video_auth
		video_data3 = connection.getURL(video_url2.replace('m3u8','json'))
		video_url3 = simplejson.loads(video_data3)
		for video_keys in BITRATETABLE.iterkeys():
			bitrate = int(video_keys)
			bitrates.append((bitrate, bitrate))
	return bitrates	
		
def play_video(SITE, BRANDID, PARTNERID):
	try:
		qbitrate = common.args.quality
	except:
		qbitrate = None
	video_id, video_type = common.args.url.split('#')
	hbitrate = -1
	lbitrate = -1
	sbitrate = int(addon.getSetting('quality'))
	localhttpserver = False
	video_auth = get_authorization(BRANDID, video_id, video_type)
	if video_auth is False:
		video_url = VIDEOLIST % BRANDID + '001/-1/-1/-1/' + video_id + '/-1/-1'
		video_data = connection.getURL(video_url)
		try:
			video_data2 = simplejson.loads(video_data)['videos']['video']
			video_format = video_data2['assets']['asset'][0]['@format']
			video_closedcaption = video_data2['closedcaption']['@enabled']
		except:
			try:
				video_data2 = simplejson.loads(video_data)['videos']['video']
				video_format = video_data2['assets']['asset']['@format']
				video_closedcaption = video_data2['closedcaption']['@enabled']
			except:
				video_format = 'MOV'
				video_closedcaption = 'false'
		video_id = video_id.replace('VDKA','')
		if video_format != 'MOV':
			if video_format == 'MP4':
				video_url = PLAYLISTMP4 % (PARTNERID, PARTNERID) + video_id
			else:
				video_url = PLAYLISTM3U % (PARTNERID, PARTNERID) + video_id
			video_data = connection.getURL(video_url)
			video_url2 = m3u8.parse(video_data)
			for video_index in video_url2.get('playlists'):
				bitrate = int(video_index.get('stream_info')['bandwidth'])
				print bitrate, sbitrate * 1000
				if qbitrate is  None:
					if bitrate > hbitrate and bitrate <= sbitrate  * 1000 :
						hbitrate = bitrate
						playpath_url = video_index.get('uri')
				else:
					if bitrate == qbitrate:
						playpath_url = video_index.get('uri')
			finalurl = playpath_url
		elif  video_format == 'MOV':
			player._localHTTPServer = False
			playpath_url = None
			video_url = PLAYLISTMOV % (PARTNERID, PARTNERID) + video_id
			video_data = connection.getURL(video_url)
			video_tree = BeautifulSoup(video_data, 'html.parser')
			base_url = video_tree('baseurl')[0].string
			video_url2 = video_tree.findAll('media')
			if qbitrate is None:
				for video_index in video_url2:
					bitrate = int(video_index['bitrate'])
					if bitrate < lbitrate or lbitrate == -1:
						lbitrate = bitrate
						lplaypath_url = video_index['url']	
					if bitrate > hbitrate and bitrate <= sbitrate:
						hbitrate = bitrate
						playpath_url = video_index['url']
			else:
				playpath_url = video_tree.find('media', bitrate = qbitrate)['url']
			if playpath_url is None:
				playpath_url = lplaypath_url
			finalurl = base_url + ' playpath=' + playpath_url + ' swfUrl=' + SWFURL + ' swfVfy=true'
		#else:
		#	finalurl = PLAYLISTM3U % (PARTNERID, PARTNERID) + video_id
	else:
		video_url = VIDEOLIST % BRANDID + '002/-1/-1/-1/' + video_id + '/-1/-1'
		video_data = connection.getURL(video_url)
		video_data2 = simplejson.loads(video_data)['videos']['video']
		video_closedcaption = video_data2['closedcaption']['@enabled']
		try:
			video_url2 = video_data2['assets']['asset']['$'] + video_auth
		except:
			video_url2 = video_data2['assets']['asset'][1]['$'] + video_auth
		video_data3 = connection.getURL(video_url2.replace('m3u8','json'))
		video_url3 = simplejson.loads(video_data3)
		for video_keys in BITRATETABLE.iterkeys():
			bitrate = int(video_keys)
			if qbitrate is None:
				if bitrate > hbitrate and bitrate <= sbitrate:
					hbitrate = bitrate
					video_url4 = video_url3['url'].replace('__ray__', BITRATETABLE[video_keys])
			else:
				if qbitrate == bitrate:
					video_url4 = video_url3['url'].replace('__ray__', BITRATETABLE[video_keys])
		video_url4 = video_url4.replace('https','http').replace('json','m3u8')
		if common.use_proxy():
		
			video_data4 = re.sub(r"\#EXT-X-DISCONTINUITY\n","", connection.getURL(video_url4))
			key_url = re.compile('URI="(.*?)"').findall(video_data4)[0]
			key_data = connection.getURL(key_url)		
			key_file = open(ustvpaths.KEYFILE % '0', 'wb')
			key_file.write(key_data)
			key_file.close()
			localhttpserver = True
			filestring = 'XBMC.RunScript(' + os.path.join(ustvpaths.LIBPATH,'proxy.py') + ', 12345)'
			xbmc.executebuiltin(filestring)
			time.sleep(20)
			video_data4 = video_data4.replace(key_url, 'http://127.0.0.1:12345/play0.key')
			playfile = open(ustvpaths.PLAYFILE, 'w')
			playfile.write(video_data4)
			playfile.close()
			finalurl = ustvpaths.PLAYFILE
		else:
			finalurl = video_url4
			player._localHTTPServer = False
	if (video_closedcaption == 'true') and (addon.getSetting('enablesubtitles') == 'true'):
		try:
			closedcaption = CLOSEDCAPTIONHOST + video_data2['closedcaption']['src']['$'].split('.com')[1]
			convert_subtitles(closedcaption)
			player._subtitles_Enabled = True
		except:
			video_closedcaption = 'false'
	item = xbmcgui.ListItem(path = finalurl)
	try:
		item.setThumbnailImage(common.args.thumb)
	except:
		pass
	try:
		item.setInfo('Video', {	'title' 	  : common.args.name,
								'season' 	  : common.args.season_number,
								'episode' 	  : common.args.episode_number,
								'TVShowTitle' : common.args.show_title})
	except:
		pass
	xbmcplugin.setResolvedUrl(pluginHandle, True, item)
	while player.is_active:
		player.sleep(250)

def clean_subs(data):
	br = re.compile(r'<br.*?>')
	tag = re.compile(r'<.*?>')
	space = re.compile(r'\s\s\s+')
	apos = re.compile(r'&amp;apos;')
	sub = br.sub('\n', str(data))
	sub = tag.sub(' ', sub)
	sub = space.sub(' ', sub)
	sub = apos.sub('\'', sub)
	return sub

def convert_subtitles(closedcaption):
	str_output = ''
	subtitle_data = connection.getURL(closedcaption, connectiontype = 0)
	subtitle_data = BeautifulSoup(subtitle_data, 'html.parser', parse_only = SoupStrainer('div'))
	lines = subtitle_data.find_all('p')
	for i, line in enumerate(lines):
		if line is not None:
			sub = clean_subs(common.smart_utf8(line))
			start_time_hours, start_time_rest = line['begin'].split(':', 1)
			start_time_hours = '%02d' % (int(start_time_hours) - 1)
			start_time = common.smart_utf8(start_time_hours + ':' + start_time_rest.replace('.', ','))
			end_time_hours, end_time_rest = line['end'].split(':', 1)
			end_time_hours = '%02d' % (int(end_time_hours) - 1)
			end_time = common.smart_utf8(end_time_hours + ':' + end_time_rest.replace('.', ','))
			str_output += str(i + 1) + '\n' + start_time + ' --> ' + end_time + '\n' + sub + '\n\n'
	file = open(ustvpaths.SUBTITLE, 'w')
	file.write(str_output)
	file.close()
	return True

def get_authorization(brandid, video_id, video_type):
	auth_time = time.time()
	parameters = {	'video_id' : video_id,
					'__rnd' : auth_time,
					'device' : '001',
					'brand' : brandid,
					'video_type' : video_type }
	auth_data = connection.getURL(GETAUTHORIZATION, parameters)
	try:
		auth_sig = '?' + simplejson.loads(auth_data)['entitlement']['uplynk']['sessionKey']
	except:
		auth_sig = False
	return auth_sig