#!/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
#

import urllib2, urllib
import datetime, re, sys,os
import requests, json
import ssl
if "_create_unverified_context" in dir(ssl):
    ssl._create_default_https_context = ssl._create_unverified_context

try:
    from requests.packages.urllib3.exceptions import InsecureRequestWarning
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
except:
    pass
from collections import OrderedDict
import ConfigParser
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 SourceBase(object):
    """Stream source base class"""

    def __init__(self,country="lv"):
        self.name = "name"
        self.title = "Title"
        self.img = ""
        self.desc = ""
        self.options = OrderedDict()
        self.config_file = ""
        self.url = "http://www.bbb.com/"
        self.headers = headers2dict("""
User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
""")

    def login(self,user="",password=""):
        return False

    def logout(self):
        return True

    def get_content(self,data):
        ### To be overriden in child class
        return [("..atpakaļ","back","back.png","Kļūda, atgriezties atpakaļ")]

    def is_video(self,data):
        ### To be overriden in child class
        return False

    def get_streams(self,data):
        ### Normally to be overrided in child class

        if not self.is_video(data):
            return []
        content = self.get_content(data)
        stream = util.item()
        stream["name"] = content[0].encode("utf8") if isinstance(content[0],unicode) else content[0]
        stream["url"] = content[1].encode("utf8") if isinstance(content[1],unicode) else content[1]
        stream["img"] = content[2].encode("utf8") if isinstance(content[2],unicode) else content[2]
        stream["desc"] = content[3].encode("utf8") if isinstance(content[3],unicode) else content[3]
        stream["type"] = stream_type(content[1]).encode("utf8")
        return[stream]

    def get_epg(self,data):
        ### Normally to be overrided in child class
        return [self.get_info(data)]

    def options_read(self):
        if not ("options" in dir(self) and self.options): # process options only if self.options defined, self.config_file should be defined too
            return None
        config = ConfigParser.ConfigParser()
        if os.path.exists(self.config_file):
            options0 = self.options
            config.read(self.config_file)
            self.options = OrderedDict(config.items(self.name))
            for k in options0:
                if not k in self.options:
                    self.options[k] = options0[k]
                    self.options_write(self.options)
        else:
            self.options_write(self.options)
        return self.options

    def options_write(self,options):
        config = ConfigParser.ConfigParser()
        config.add_section(self.name)
        for k in options.keys():
            config.set(self.name, k,options[k])
        with open(self.config_file,"w") as f:
            config.write(f)
        self.options = OrderedDict(config.items(self.name))

    def call(self, data,params=None,headers=None,lang=""):
        if not headers: headers = self.headers
        url = self.url+data
        result = self._http_request(url,params,headers=headers)
        return result

    def call_json(self, data,params=None,headers=None,lang=""):
        result = self.call(data,params,headers)
        if result:
            result = json.loads(result)
            return result
        else:
            raise "No data returned"

    def _http_request(self, url,params = None, headers=None):
        if not headers:
            headers = self.headers if "headers" in dir(self) else headers2dict("User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0")
        try:
            if params:
                r = requests.post(url, data=params, headers=headers,verify=False)
            else:
                r = requests.get(url, headers=headers,verify=False)
            return r.content
        except Exception as ex:
            if "read" in ex:
                content = ex.read()
            else:
                content = None
            return content

    @staticmethod
    def stream_type(data):
        return stream_type(data)

    @staticmethod
    def parse_data(data):
        if "::" in data:
            source = data.split("::")[0]
            data = data.split("::")[1]
        else:
            source = ""
        path = data.split("?")[0]
        plist = path.split("/")
        clist = plist[0]
        params = data[data.find("?"):] if "?" in data else ""
        qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w\-]+",params)))
        return source,data,path,plist,clist,params,qs

def stream_type(data):
    data = data.lower()
    m = re.search(r"^(\w+)://", data)
    prefix = m.group(1) if m else ""
    if prefix in ("http","https"):
        if ".m3u8" in data:
            return "hls"
        elif ".mpd" in data:
            return "dash"
        else:
            return "http"
    else:
        return prefix

if __name__ == "__main__":
    pass