# -*- coding: UTF-8 -*-

import os, sys, re, xbmc, xbmcgui, xbmcaddon, string, urllib, urllib2, time, xml.etree.ElementTree as XMLTree
from utilities import log
try: import simplejson as json
except: import json

_                = sys.modules[ "__main__" ].__language__
__profile__      = sys.modules[ "__main__" ].__profile__
__version__      = sys.modules[ "__main__" ].__version__

useragent        = 'script.xbmc.subtitles/' + __version__
apiurl           = "http://api.bierdopje.com/"
apikey           = "369C2ED4261DE9C3"
showids_filename = os.path.join( __profile__ ,"bierdopje_show_ids.txt" )
sleeptime        = 0.6
releases_types   = ['web-dl', '480p', '720p', '1080p', 'h264', 'x264', 'xvid', 'aac20', 'hdtv', 'dvdrip', 'ac3', 'bluray', 'dd51', 'divx', 'proper', 'repack', 'pdtv', 'rerip', 'dts']

#====================================================================================================================
# Functions
#====================================================================================================================

def apicall(command, paramslist):
    time.sleep(sleeptime)
    url = apiurl + apikey + "/" + command
    for param in paramslist:
        url = url + "/" + urllib.quote_plus(param)
    log( __name__ ," getting url '%s'" % url )
    try:
        request = urllib2.Request(url)
        request.add_header("User-agent", useragent)
        response = urllib2.urlopen(request)
    except IOError, e:
        if hasattr(e, 'reason'):
            log( __name__ ," failed to reach Bierdopje site, reason: '%s'." % e.reason )
            okdialog = xbmcgui.Dialog()
            ok = okdialog.ok("Error", "Failed to reach Bierdopje." % e.reason)
        elif hasattr(e, 'code'):
            log( __name__ ," Bierdopje site couldn't fulfill the request, HTTP code: '%s'." % e.code )
            okdialog = xbmcgui.Dialog()
            ok = okdialog.ok("Error", "Bierdopje  couldn't fulfill the request." % e.code)
        else:
            log( __name__ ," unkown error while contacting Bierdopje site")
            okdialog = xbmcgui.Dialog()
            ok = okdialog.ok("Error", "Unkown error while contacting Bierdopje.")
    else:
        try:
            xml = XMLTree.parse(response)
            status = gettextelements(xml, "response/status")
        except:
            okdialog = xbmcgui.Dialog()
            ok = okdialog.ok("Error", "unexpected response from Bierdopje.")
            log( __name__ ," unexpected response from Bierdopje site.")
            return None
        if status == ["false"]:
            log( __name__ ," failed to get proper response from Bierdopje site (status = false)")
            return None
        else:
            return xml

def gettextelements(xml, path):
    textelements = []
    try:
        elements = xml.findall(path)
    except:
        return
    for element in elements:
        textelements.append(element.text)
    return textelements

def getshowid(showname):
    showid = None
    showids = {}
    if os.path.isfile(showids_filename):
        showids_filedata = file(showids_filename,'r').read()
        showids = eval(showids_filedata)
        if showname in showids:
            if showids[showname] != '16178':
                log( __name__ ," show id for '%s' is '%s' (from cachefile '%s')" % (showname, showids[showname], showids_filename))
                return showids[showname]
            else:
                log( __name__ ," removing invalid show id '%s' for '%s' from from cachefile '%s'" % (showids[showname], showname, showids_filename))
                del showids[showname]
                file(showids_filename,'w').write(repr(showids))
    if showid is None:
        try:
            playerid_query = '{"jsonrpc": "2.0", "method": "Player.GetActivePlayers", "id": 1}'
            playerid = json.loads(xbmc.executeJSONRPC(playerid_query))['result'][0]['playerid']
            tvshowid_query = '{"jsonrpc": "2.0", "method": "Player.GetItem", "params": {"playerid": ' + str(playerid) + ', "properties": ["tvshowid"]}, "id": 1}'
            tvshowid = json.loads(xbmc.executeJSONRPC (tvshowid_query))['result']['item']['tvshowid']
            tvdbid_query = '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShowDetails", "params": {"tvshowid": ' + str(tvshowid) + ', "properties": ["imdbnumber"]}, "id": 1}'
            tvdbid = json.loads(xbmc.executeJSONRPC (tvdbid_query))['result']['tvshowdetails']['imdbnumber']
        except:
            log( __name__ ," Failed to find TVDBid in database")
        else:
            if tvdbid != '':
                response = apicall("GetShowByTVDBID",[tvdbid])
                if response is not None:
                    showid = gettextelements(response,"response/showid")
                    if len(showid) == 1:
                        log( __name__ ," show id for '%s' is '%s' (found by TVDBid %s)" % (showname, str(showid[0]), tvdbid))
                        showids[showname] = str(showid[0])
                        file(showids_filename,'w').write(repr(showids))
                        return str(showid[0])
    response = apicall("GetShowByName",[showname])
    if response is not None:
        showid = gettextelements(response,"response/showid")
        if len(showid) == 1:
            log( __name__ ," show id for '%s' is '%s'" % (showname, str(showid[0])) )
            showids[showname] = str(showid[0])
            file(showids_filename,'w').write(repr(showids))
            return str(showid[0])
    if (showid is None) and ("'" in showname):
        response = apicall("GetShowByName",[string.replace(showname,"'","''")])
        if response is not None:
            showid = gettextelements(response,"response/showid")
            if len(showid) == 1:
                log( __name__ ," show id for '%s' is '%s' (replaced ' with '')" % (string.replace(showname,"'","''"), str(showid[0])) )
                showids[showname] = str(showid[0])
                file(showids_filename,'w').write(repr(showids))
                return str(showid[0])
    okdialog = xbmcgui.Dialog()
    ok = okdialog.ok("Error", "Failed to get a show id from Bierdopje for " + showname)
    log( __name__ ," failed to get a show id for '%s'" % showname )
    return None

def getrating(subsfile, videofile):
    rating = 0
    videofile = "".join(string.split(videofile, '.')[:-1])
    videofile = string.lower(videofile)
    subsfile = string.lower(subsfile)
    videofile = string.replace(videofile, '.', '')
    subsfile = string.replace(subsfile, '.', '')
    for release_type in releases_types:
        if (release_type in videofile) and (release_type in subsfile): rating += 1
    if string.split(videofile, '-')[-1] == string.split(subsfile, '-')[-1] : rating += 1
    if rating > 0:
        rating = rating * 2 - 1
        if rating > 9: rating = 9
    return rating

def isexactmatch(subsfile, videofile):
    videofile = "".join(string.split(videofile, '.')[:-1])
    videofile = string.lower(videofile)
    videofile = string.replace(videofile, ' ', '.')
    videofile = string.replace(videofile, '.', '')
    subsfile = string.replace(subsfile, '.', '')
    subsfile = string.lower(subsfile)
    log( __name__ ," comparing subtitle file with videofile (sync?):\nsubtitlesfile  = '%s'\nvideofile      = '%s'" % (subsfile, videofile) )
    if string.find(subsfile, videofile) > -1:
        log( __name__ ," found matching subtitle file, marking it as 'sync': '%s'" % (subsfile) )
        return True
    else:
        # try to strip the episode title from the videofile and compare again
        episodetitle = None
        for release_type in releases_types:
            match = re.search("s\d\de\d\d(.+)" + release_type, videofile)
            if match:
                if episodetitle is None: episodetitle = match.group(1)
                elif len(episodetitle) > len(match.group(1)): episodetitle = match.group(1)
        if (episodetitle not in releases_types) and (episodetitle is not None):
            log( __name__ ," found episodetitle: '%s'" % (episodetitle))
            videofile = string.replace(videofile, episodetitle, '')
            log( __name__ ," comparing subtitle file with videofile, excluding episode title (sync?):\nsubtitlesfile  = '%s'\nvideofile      = '%s'" % (subsfile, videofile) )
            if string.find(subsfile, videofile) > -1:
                log( __name__ ," found matching subtitle file, marking it as 'sync': '%s'" % (string.lower(subsfile)) )
                return True
            else:
                return False

def getallsubs(showid, file_original_path, tvshow, season, episode, languageshort, languagelong, subtitles_list):
    not_sync_list = []
    response = apicall("GetAllSubsFor",[showid, str(season), str(episode), languageshort])
    if response is not None:
        filenames = gettextelements(response,"response/results/result/filename")
        downloadlinks = gettextelements(response,"response/results/result/downloadlink")
        if len(filenames) > 0:
            log( __name__ ," found %s %s subtitles" % (len(filenames), languagelong))
            for i in range(len(filenames)):
                if string.lower(filenames[i][-4:]) == ".srt":
                    filenames[i] = filenames[i][:-4]
                if isexactmatch(filenames[i], os.path.basename(file_original_path)):
                    sync = True
                    rating = 10
                else:
                    sync = False
                    rating = getrating(filenames[i], os.path.basename(file_original_path))
                subtitles_list.append({'rating': str(rating), 'no_files': 1, 'format': 'srt', 'movie':  tvshow, 'language_id': '', 'filename': filenames[i], 'sync': sync, 'link': downloadlinks[i], 'language_flag': 'flags/' + languageshort + '.gif', 'language_name': languagelong, 'ID': '0'})
        else:
            log( __name__ ," found no %s subtitles" % (languagelong))

def search_subtitles( file_original_path, title, tvshow, year, season, episode, set_temp, rar, lang1, lang2, lang3, stack ): #standard input
    subtitles_list = []
    msg = ""
    if len(tvshow) > 0:
        tvshow_id= getshowid(tvshow)
        if tvshow_id is not None:
            dutch = 0
            if string.lower(lang1) == "dutch": dutch = 1
            elif string.lower(lang2) == "dutch": dutch = 2
            elif string.lower(lang3) == "dutch": dutch = 3
            english = 0
            if string.lower(lang1) == "english": english = 1
            elif string.lower(lang2) == "english": english = 2
            elif string.lower(lang3) == "english": english = 3
            if dutch > 0:
                getallsubs(tvshow_id, file_original_path, tvshow, season, episode, "nl", "Dutch", subtitles_list)
            if english > 0:
                getallsubs(tvshow_id, file_original_path, tvshow, season, episode, "en", "English", subtitles_list)
            subtitles_list.sort(key=lambda x: [ x['sync'], x['rating']], reverse = True)
            if ((dutch > 0) and (english > 0) and (dutch < english)):
                subtitles_list.sort(key=lambda x: [ x['language_name']])
            if ((dutch > 0) and (english > 0) and (dutch > english)):
                subtitles_list.sort(key=lambda x: [ x['language_name']], reverse = True)
            if ((dutch == 0) and (english == 0)):
                msg = "Won't work, Bierdopje is only for Dutch and English subtitles."
    else:
        msg = "Won't work, Bierdopje is only for tv shows."
    return subtitles_list, "", msg #standard output

def download_subtitles (subtitles_list, pos, zip_subs, tmp_sub_dir, sub_folder, session_id): #standard input
    local_tmp_file = os.path.join(tmp_sub_dir, "bierdopje_subs.srt")

    log( __name__ ," downloading subtitles from url '%s'" % subtitles_list[pos][ "link" ] )
    try:
        request = urllib2.Request(subtitles_list[pos][ "link" ])
        request.add_header("User-agent", useragent)
        response = urllib2.urlopen(request)
    except:
        okdialog = xbmcgui.Dialog()
        ok = okdialog.ok("Error", "Failed to contact Bierdopje site.")
        log( __name__ ," failed to get url '%s'" % subtitles_list[pos][ "link" ] )
    else:
        log( __name__ ," saving subtitles to '%s'" % local_tmp_file )
        try:
            local_file_handle = open(local_tmp_file, "w" + "b")
            local_file_handle.write(response.read())
            local_file_handle.close()
        except:
            okdialog = xbmcgui.Dialog()
            ok = okdialog.ok("Error", "Failed to save subtitles.")
            log( __name__ ," failed to save subtitles to '%s'" % local_tmp_file )
        else:
            language = subtitles_list[pos][ "language_name" ]
            return False, language, local_tmp_file #standard output