import os
import platform
import re
import requests

from kodi_six import xbmc, xbmcgui, xbmcaddon
from kodi_six.utils import py2_encode

from six.moves import urllib_parse

from elementum.logger import log
from elementum.osarch import PLATFORM
from elementum.addon import ADDON, ADDON_NAME, ADDON_ICON

try:
    import simplejson as json
except ImportError:
    import json

def translatePath(path):
    try:
        from xbmcvfs import translatePath
    except ImportError:
        from xbmc import translatePath

    return translatePath(path)

def notify(message, header=ADDON_NAME, time=5000, image=ADDON_ICON):
    sound = ADDON.getSetting('do_not_disturb') == 'false'
    dialog = xbmcgui.Dialog()
    return dialog.notification(getLocalizedLabel(header), getLocalizedLabel(message), toUtf8(image), time, sound)

def dialog_ok(message, header=ADDON_NAME):
    dialog = xbmcgui.Dialog()
    return dialog.ok(getLocalizedLabel(header), getLocalizedLabel(message))

def getLocalizedText(text):
    try:
        return re.sub(r'LOCALIZE\[(\d+)\]', getLocalizedStringMatch, text)
    except:
        return text

def getLocalizedLabel(label):
    try:
        if "LOCALIZE" not in label:
            return py2_encode(label)
        if ";;" not in label and label.endswith(']'):
            return py2_encode(getLocalizedString(int(label[9:-1])))
        else:
            parts = label.split(";;")
            translation = getLocalizedString(int(parts[0][9:14]))
            for i, part in enumerate(parts[1:]):
                if part[0:8] == "LOCALIZE":
                    parts[i + 1] = getLocalizedString(int(part[9:14]))
                else:
                    parts[i + 1] = py2_encode(parts[i + 1])

            return py2_encode(translation % tuple(parts[1:]), 'utf-8', 'ignore')
    except Exception as e:
        log.error("Cannot decode the label: %s, Error: %s" % (label, e))
        return label

def getLocalizedStringMatch(match):
    try:
        return ADDON.getLocalizedString(int(match.group(1)))
    except:
        return match.group(1)

def getLocalizedString(stringId):
    try:
        return py2_encode(ADDON.getLocalizedString(stringId), 'utf-8', 'ignore')
    except:
        return stringId

def getElementumLocalizedString(stringId):
    ELEMENTUM_ADDON = xbmcaddon.Addon('plugin.video.elementum')
    try:
        return py2_encode(ELEMENTUM_ADDON.getLocalizedString(stringId), 'utf-8', 'ignore')
    except:
        return stringId

def toUtf8(string):
    if isinstance(string, bytes):
        string = string.decode('utf-8', 'ignore')
    return py2_encode(string)

def system_information():
    build = xbmc.getInfoLabel("System.BuildVersion")
    log.info("System information: %(os)s_%(arch)s %(version)s" % PLATFORM)
    log.info("Kodi build version: %s" % build)
    log.info("OS type: %s" % platform.system())
    log.info("uname: %s" % repr(platform.uname()))
    return PLATFORM

def getShortPath(path):
    if PLATFORM["os"] == "windows":
        return getWindowsShortPath(path)
    return path

def getWindowsShortPath(path):
    try:
        import ctypes
        import ctypes.wintypes

        ctypes.windll.kernel32.GetShortPathNameW.argtypes = [
            ctypes.wintypes.LPCWSTR,  # lpszLongPath
            ctypes.wintypes.LPWSTR,  # lpszShortPath
            ctypes.wintypes.DWORD  # cchBuffer
        ]
        ctypes.windll.kernel32.GetShortPathNameW.restype = ctypes.wintypes.DWORD

        buf = ctypes.create_unicode_buffer(1024)  # adjust buffer size, if necessary
        ctypes.windll.kernel32.GetShortPathNameW(path, buf, len(buf))

        return buf.value
    except:
        return path

def download_github_folder(repo, folder, destination):
    contents_url = "https://api.github.com/repos/%s/contents/%s" % (repo, folder)
    log.info("Downloading repo content for folder: %s, to folder: %s" % (contents_url, destination))
    try:
        with requests.get(contents_url) as r:
            lists = json.loads(r.content, parse_int=str)

            downloaded = 0
            for i in lists:
                if 'download_url' not in i:
                    continue

                dest = os.path.join(destination, urllib_parse.unquote(i['download_url'].rsplit('/', 1)[1]))
                log.info("Downloading file '%s' to '%s'" % (i['download_url'], dest))

                with requests.get(i['download_url'], stream=True) as rd:
                    rd.raise_for_status()
                    with open(dest, 'wb') as f:
                        for chunk in rd.iter_content(chunk_size=8192):
                            f.write(chunk)
                downloaded += 1
            return downloaded > 0
    except Exception as e:
        log.error("Could not get list of files from github: %s" % e)
        raise

def download_current_version(repo):
    contents_url = "https://api.github.com/repos/%s/git/refs/tags" % (repo)
    log.debug("Downloading repo releases: %s" % (contents_url))
    try:
        with requests.get(contents_url) as r:
            lists = json.loads(r.content, parse_int=str)

            ref = lists[-1]["ref"]
            if ref.find('/'):
                return ref.rsplit('/', 1)[1]

            return ""
    except Exception as e:
        log.error("Could not get list of tags from github: %s" % e)
        raise


def read_current_version(dest_dir):
    p = os.path.join(dest_dir, "version")
    if os.path.exists(p):
        try:
            with open(p, 'r') as file:
                return file.read().replace('\n', '')
        except:
            pass
    return ""

def write_current_version(dest_dir, version):
    p = os.path.join(dest_dir, "version")
    try:
        with open(p, 'w') as file:
            file.write(version)
            file.close()
    except:
        pass
