#!/usr/bin/env python
# coding=utf8
#
# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
#
try:
    import json
except:
    import simplejson as json

import requests
try:
    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
except:
    pass
import urlparse, urllib
import datetime, time,re, sys,os
from collections import OrderedDict
import ssl
if "_create_unverified_context" in dir(ssl):
    ssl._create_default_https_context = ssl._create_unverified_context

from SourceBase import SourceBase
try:
    import util
except:
    parent = os.path.dirname(os.path.abspath(__file__))
    parent = os.sep.join(parent.split(os.sep)[:-1])
    sys.path.insert(0,parent)
    import util

headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])

class Source(SourceBase):

    def __init__(self,language="en",cfg_path=None):
        self.hidden = True # nerāda menu nestrādājošos avotus
        self.name = "viaplay"
        self.title = "viaplay.lv"
        self.img = "viaplay.png"
        self.desc = "Viaplay.lv saturs"
        self.url = "https://viaplay.lv/"
        self.headers = headers2dict("""
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Upgrade-Insecure-Requests: 1
        """)
        #self.language=language
        cur_directory = os.path.dirname(os.path.abspath(__file__))
        if not cfg_path: cfg_path = cur_directory
        self.config_file = os.path.join(cfg_path,self.name+".cfg")
        self.options = OrderedDict([("user","change_user"),("password","change_password"),("device","")])
        self.options_read()
        self.device = self.options["device"]
        self.r = None # requests
        self.play_session = None
        self.s = None

    def login(self,user="",password=""):
        self.options_read()
        if not user: user=self.options["user"]
        if not password: password = self.options["password"]
        self.s = requests.Session()

        ### Dabu sesijas ID ===
        headers = headers2dict("""
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://viaplay.lv/
Cookie: ott_cookies_confirmed=1;
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
""")
        r = requests.get(self.url,headers=headers)
        if not "PLAY_SESSION" in r.cookies:
            return False
        self.play_session = r.cookies["PLAY_SESSION"]
        self.csrfToken = re.search("csrfToken=(.+)",self.play_session).group(1)

        ### Ielogojamies ###
        headers = headers2dict("""
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://viaplay.lv/
Cookie: ott_cookies_confirmed=1; PLAY_SESSION=e618c42b377a65021298ff63309d5a907988ed1b-PSESSIONID=b010ea1b-fc5e-4a18-aa15-ebbe8b57b3f0&csrfToken=b4eb35263d9be16ef9f7b2f5d10a8ee99dfe75a8-1478051634814-63682b20f1e7e5579de6d056
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
""")
        url = "https://viaplay.lv/tdi/login/nav/form?csrfToken=%s"%self.csrfToken
        #      https://viaplay.lv/tdi/login/nav/form?_infuse=1&_ts=1490554674901&csrfToken=
        params = "nav_redirectUri=https%3A%2F%2Fviaplay.lv%2F&nav_email={}&nav_password={}".format(urllib.quote(user),urllib.quote(password))
        #         nav_redirectUri=https%3A%2F%2Fviaplay.lv%2F&nav_email=ivars777%40gmail.com&nav_password=xxxx&nav_remember=true
        headers["Cookie"] = "ott_cookies_confirmed=1; PLAY_SESSION=%s;"%self.play_session
        if self.device:
            headers["Cookie"] += "ott_dids=%s"%self.device
        #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
        r = requests.post(url,params,headers=headers,allow_redirects=False)
        if not "Set-Cookie" in r.headers:
            self.play_session = None
            return False
        if not "ott_web_sac" in r.cookies:
            self.play_session = None
            return False
        self.ott = r.cookies["ott_web_sac"]

        ### Dabu iekārtas ID ###
        if not self.device:
            headers = headers2dict("""
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Accept: application/xml, text/xml, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: https://viaplay.lv/movies/me-and-earl-and-the-dying-girl
DNT: 1
Connection: keep-alive    """)
            url = "https://viaplay.lv/tdi/account/device/create?_infuse=1&csrfToken=%s"%self.csrfToken
            params = "successRedirectUri=https%3A%2F%2Fviaplay.lv%2Fmovies%2F&slotId=&title=Enigma2"
            headers["Cookie"] = "PLAY_SESSION=%s; ott_cookies_confirmed=1; ott_web_sac=%s;"%(self.play_session,self.ott)
            #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
            r = requests.post(url,params,headers=headers,allow_redirects=False)
            if not ("Set-Cookie" in r.headers and "ott_dids" in r.headers["Set-Cookie"]):
                self.play_session = None
                return False
            self.device =  r.cookies["ott_dids"]
            self.options["device"] = self.device
            self.options_write(self.options)
        return True

    def logout(self):
        return True

    def is_logedin(self):
        if self.play_session:
            return True
        else:
            return False

    def get_video_info(self,vid):
        import demjson
        ### Dabu strimus ###
        headers = headers2dict("""
Host: viaplay.lv
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46
Accept: application/xml, text/xml, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
DNT: 1
Connection: keep-alive
Referer: https://viaplay.lv/
""")
        url = "https://viaplay.lv/prehravac/init?_infuse=1&productId=%s"%vid #t110623
        headers["Cookie"] = "ott_cookies_confirmed=1; ott_dids=%s; PLAY_SESSION=%s"%(self.device,self.play_session)
        r = requests.get(url,headers=headers,allow_redirects=False)
        statuss = re.search("<status>(.+?)</status>", r.content).group(1)
        if statuss.lower() <> "ok":
            raise Exception(statuss)
        #print r.content
        m = re.search(r"<!\[CDATA\[\s+var TDIPlayerOptions = (.+?);[\n\t\s]+\]\]>\s+</script>", r.content, re.DOTALL)
        if not m:
            raise "Can not find stream info"
        txt = m.group(1)
        txt = re.sub("// .+$", "", txt, flags=re.MULTILINE)
        #print txt
        #for m in re.finditer("// .+$", txt, re.MULTILINE):
        #    txt = txt[:m.start()] + txt[m.end():]
        #print txt
        js = demjson.decode(txt)
        return js
        #return txt


    def get_content(self, data):
        print "[%s] get_content:"%self.name, data
        source,data,path,plist,clist,params,qs = self.parse_data(data)
        content=[]
        content.append(("..return", "back","back.png","Return back"))

        if clist=="home":
            content.extend([
                ("Search", "viaplay::search-results-all?query={0}",self.img,"Meklēt"),
                ("Filmas", "viaplay::movies",self.img,"Filmas"),
                ("Seriāli", "viaplay::series",self.img,"Seriāli"),
                ("Bērniem", "viaplay::kids",self.img,"Bērniem"),
                ("Dokumentalās filmas", "viaplay::documentary",self.img,"Dokumentalās filmas"),
                ("Sports", "viaplay::live",self.img,"Sports"),
             ])
            return content

        ### Meklēt ###
        elif clist=="search-results-all":
            url = "https://viaplay.lv/"+data
            r = self._http_request(url)
            result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
            for item in result:
                vid = item[0]
                data2 = item[1].replace("https://viaplay.lv/","")
                img = item[2]
                ep = item[3]
                title= item[4]
                seas = item[5].replace("\n","").replace("\t","")
                desc = item[6]
                desc2 = item[7]
                if ep==title:
                    title = "%s (%s)"%(title,seas)
                else:
                    title = "%s - %s%s"%(title,seas,ep)
                desc = "%s\n%s\n%s"%(title,desc2,desc)
                content.append((title,self.name+"::"+data2,img,desc))
            return content

        ### Sadalas ##
        elif data in ["movies","series","kids","documentary"]:
            r = self._http_request(self.url+data)
            # https://viaplay.lv/tdi/movies/next?sections[]=MOVIES&genres[]=a3591&sort[]=latest&offset=0
            # https://viaplay.lv/tdi/series/next?sections[]=SERIES&sort[]=latest&offset=0
            # https://viaplay.lv/tdi/kids/next?sections[]=KIDS&cat[]=SERIES&cat[]=MOVIE&sort[]=latest&offset=18
            # https://viaplay.lv/kids?sections[]=KIDS&cat[]=SERIES&sort[]=latest
            sections =  {"movies":"MOVIES","series":"SERIES","kids":"KIDS","documentary":"DOCUMENTS"}
            nosaukums = {"movies":"Flmas","series":"Seriāli","kids":"Bērnu","documentary":"Dokumentalās"}
            #availability = {"new":"jaunākās","last":"pēdējā iespēja"}
            sort = OrderedDict([("latest","jaunākais"),("title","pēc nosaukuma"),("popular","pēc popularitātes"),("year","pēc gada")])
            for s in sort:
                if data in ("movies","series"):
                    title = "%s - %s"%(nosaukums[data],sort[s])
                    data2 = "%s/next?sections[]=%s&sort[]=%s"%(data,sections[data],s)
                    content.append((title,self.name+"::"+data2,self.img,title))
                else:
                    title = "%s filmas - %s"%(nosaukums[data],sort[s])
                    data2 = "%s/next?sections[]=%s&cat[]=MOVIE&sort[]=%s"%(data,sections[data],s)
                    content.append((title,self.name+"::"+data2,self.img,title))
                    title = "%s seriāli - %s"%(nosaukums[data],sort[s])
                    data2 = "%s/next?sections[]=%s&cat[]=SERIES&sort[]=%s"%(data,sections[data],s)
                    content.append((title,self.name+"::"+data2,self.img,title))

            # Pievienojam žanru sarakstu
            result = re.findall(r'name="genres\[\]" value="([^"]+)">.+?class="">([^<]+)</label>', r, re.DOTALL)
            for item in result:
                s = "latest"
                genre = item[1].replace("&amp;","&")
                title = "%s: %s"%(nosaukums[data],genre)
                data2 = "%s/next?sections[]=%s&genres[]=%s&sort[]=%s"%(data,sections[data],item[0],s)
                content.append((title,self.name+"::"+data2,self.img,title))

            return content

        ### Filmu/seriālu/sēriju saraksts ###
        elif clist in ("movies","series","kids","documentary") and plist[1] == "next":
            url = "https://viaplay.lv/tdi/"+data
            r = self._http_request(url)
            if clist == "series" and "season" in qs:
                result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
                for item in result:
                    vid = item[0]
                    data2 = item[1].replace("https://viaplay.lv/","")
                    img = item[2]
                    ep = item[3]
                    title= item[4]
                    seas = item[5]
                    desc = item[6]
                    desc2 = item[7]
                    title = "%s - %s%s"%(title,seas,ep)
                    desc = "%s\n%s\n%s"%(title,desc2,desc)
                    content.append((title,self.name+"::"+data2,img,desc))
            else: # filmas
                result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p>([^<]+)</p>.+?<p class="promo-notice">([^<]+).+?<p class="is-strong detail">(.+?)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
                for item in result:
                    vid = item[0]
                    data2 = item[1].replace("https://viaplay.lv/","")
                    img = item[2]
                    title = item[3]
                    year = item[4]
                    year  = year.replace("\n","").replace("\t","")
                    title = title +"(%s)"%year
                    desc= item[5]
                    genre = re.findall(">([^<]+)<", item[6], re.DOTALL)
                    genre = ("".join(genre)).replace("&amp;","&")
                    desc2 = item[7]
                    desc = "%s\n%s\n%s"%(genre,desc2,desc)
                    content.append((title,self.name+"::"+data2, img,desc))
            m = re.search(r"data\('href', 'https://viaplay\.lv/tdi/([^']+)'\)", r, re.DOTALL)
            if m:
                data2 = m.group(1)
                content.append(("Next page",self.name+"::"+data2,img,"Next page"))
            return content

        ### Seriāls ###
        elif clist == "series" and len(plist)==2:
            url = "https://viaplay.lv/"+data
            r = self._http_request(url)
            result = re.findall(r'<li>.*?<a class="tdi" href="https://viaplay\.lv/([^"]+)" data-related-ancestor="\.js-tdi-items-filter-and-items">([^<]+)</a>.*?</li>', r, re.DOTALL)
            for item in result:
                title = item[1]
                data2 = item[0]
                data2 = data2.replace("series/","series/next/")
                data2 = data2+"&sort[]=ord"
                #series/littlest-pet-shop?season=t6821
                #series/next/peppa-pig?season=t8430
                # &sort[]=ord
                if "availability=" in data2: continue
                content.append((title,self.name+"::"+data2,self.img,title)) #TODO bilde
            return content

    def is_video(self,data):
        source,data,path,plist,clist,params,qs = self.parse_data(data)
        if clist in ("movies","documentary","kids") and len(plist)>1 and plist[1]<>"next":
            return True
        elif clist == "series"  and len(plist)>1 and plist[1] == "episode":
            return True
        else:
            return False

    def get_streams(self, data):
        print "[viaplay] get_streams:", data
        if not self.is_video(data):
            return []
        source,data,path,plist,clist,params,qs = self.parse_data(data)
        if not self.is_logedin():
            self.login()
        if not self.is_logedin():
            raise Exception("Could not login to viaplay.lv, check username/password in options")

        streams = []
        url = "https://viaplay.lv/"+data
        r = self._http_request(url)
        if clist in ("series","livestream"): # TODO nerāda overtime u.c.
            m = re.search(r'<h1 class="is-bottom-sticked is-size-h2">(.+?)</h1>.*?<h2 class="is-size-h4">.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
            if not m:
                raise Exception("Problem getting video information")
            title = m.group(1).replace("\n"," ").replace("\t","").strip()
            title = re.sub("<[^>]+>","",title).strip()
            desc2 = m.group(2).replace("\n"," ").replace("\t","").strip()
            desc2 = re.sub("<[^>]+>","",desc2).strip()
            desc = m.group(3)
            desc = "%s\n%s"%(desc2,desc)
            vid = re.search('data-productid="(\w+)"',r).group(1)
        else:
            m = re.search(r'<h1 class="is-strong is-bottom-sticked is-size-h2" jnp-id="(\w+)">([^<]+)</h1>.*?<h2 class="is-strong is-size-h4">([^<]+)</h2>.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
            if not m:
                raise Exception("Problem getting video information")
            title = m.group(2).strip()
            title2 = m.group(3).strip()
            title = "%s | %s"%(title,title2)
            desc = m.group(5).strip()
            desc2 = m.group(4).strip()
            desc2 = re.sub("<[^>]+>","",desc2)
            desc2 = desc2.replace("\n"," ").replace("\t","")
            desc = "%s\n%s"%(desc2,desc)
            vid = m.group(1)

        js = self.get_video_info(vid)
        #for m in re.finditer(r"lang: '(?P<lang>\w+)',\s+src: '(?P<url>[^']+)',\s+type: '(?P<mime>[^']+)',\s+drm: \[(?P<drm>.+?)\]\s*\}", r, re.DOTALL):
        if not js:
            return []
        tracks = js["tracks"]
        #if not tracks["HLS"]:
        #    raise Exception("Encrypted DASH playing not yet implemented")

        captions = []
        llist = ["fr","en","ru","lv"]
        for st in js["plugins"]["settings"]["subtitles"]:
            sub = {}
            sub["url"] = st["src"]
            sub["lang"] = st["srclang"]
            sub["name"] = st["label"]
            sub["type"] = "vtt"
            sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0
            captions.append(sub)
        captions = sorted(captions,key=lambda item: item["order"],reverse=True)

        for s in tracks["HLS"] if tracks["HLS"]  else tracks["DASH"] :
            stype = "DASH" if "dash" in s["type"] else "HLS"
            if "drm" in s: ###
                # TODO, encrypted stream
                raise Exception("Can not play DRM protected stream!\nOnly local and Russian content available without DRM")
                continue
            url = s["src"]
            #urlp = util.streamproxy_encode(s["src"])
            stream = util.item()
            stream["url"]=url
            stream["resolver"] = "viaplay"
            stream["lang"]=s["lang"]
            stream["quality"]="variant"
            stream["bitrate"]= "1000000"
            stream["name"]= title
            stream["desc"]=desc
            stream["type"]=stype
            stream["subs"] = captions
            print url
            if stype=="DASH": streams.append(stream)

            if stype == "HLS": # izvelkam individuālos strimus
                r = requests.get(url)
                result = re.findall("#EXT-X-STREAM-INF:BANDWIDTH=(\d+),RESOLUTION=(\d+x\d+)\n(\w+.m3u8)", r.content)
                if not result:
                    continue
                for s2 in result:
                    ### TODO vajag lietot cookie ar tokenu no playlista requesta
                    if "set-cookie" in r.headers:
                        headers = {"Cookie":r.headers["set-cookie"]}
                    else:
                        headers={}
                    #url2 = re.sub(r"(http.*://.+/)\w+.m3u8", r"\1"+s2[2], url)
                    url2 = "/".join(url.split("/")[:-1])+"/"+s2[2]
                    #r2 = requests.get(url2,headers=headers)
                    #if "set-cookie" in r2.headers:
                        #headers = {"Cookie":r2.headers["set-cookie"]}
                    #else:
                        #headers={}
                    #url2p=util.streamproxy_encode(url2,headers)
                    stream = util.item()
                    stream["url"]=url2
                    stream["lang"]=s["lang"]
                    stream["quality"]="%s"%(s2[1])
                    stream["name"]= title
                    stream["desc"]=desc
                    stream["bitrate"]=s2[0]
                    stream["type"]="DASH" if "dash" in s["type"] else "HLS"
                    streams.append(stream)

        ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
        qlist = ["","512","640","758","1024","variant"]
        llist = ["lt","et","fr","en","ru","lv"]
        for s in streams:
            lv = llist.index(s["lang"])*10000000 if s["lang"] in llist else 0
            #qv=qlist.index(s["quality"]) if s["quality"] in qlist else 0
            qv = int(s["bitrate"]) if s["bitrate"] else 0
            s["order"] = lv+qv
            #print s["lang"],s["quality"],s["bitrate"],s["order"]

        streams = sorted(streams,key=lambda item: item["order"],reverse=True)
        return streams

    def call(self, data,params = None, headers=None):
        if not headers: headers = self.headers
        #if not lang: lang = self.country
        url = "https://viaplay.lv/tdi/" + data
        content = self._http_request(url, params, headers)
        return content

if __name__ == "__main__":
    sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
    import run
    source = Source()
    data= sys.argv[1] if len(sys.argv)>1 else source.name+"::home"
    run.run(source, data)
    sys.exit()

    r = requests.get("https://viaplay.lv/movies?sections[]=MOVIES")
    result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p class="promo-notice">([^<]+)<', r.content, re.DOTALL)
    for item in result:
        vid = item[0]
        url = item[1]
        img = item[2]
        title = item[3]
        desc= item[4]
        print "\n%s (%s):"%(title,vid)
        vinfo = c.get_video_info(vid)
        if "HLS" in vinfo["tracks"]:
            for s in vinfo["tracks"]["HLS"]:
                print "HLS %s: \n%s"%(s["lang"],s["src"])

        if "DASH" in vinfo["tracks"]:
            for s in vinfo["tracks"]["DASH"]:
                print "DASH %s: \n%s"%(s["lang"],s["src"])
        #except Exception,ex:
            #print ex.message
    #content = c.get_content(data)
    #for item in content:
    #    print item
    pass