import os
import pathlib
import sys
import xbmcaddon
import xbmcvfs
import xbmc
import xbmcgui
import zipfile
import shutil
import logging
import requests
from glob import glob
from resources.lib import kodiutils
import json
import re

from resources.modules.httpclient import HttpClient
from resources.modules.thegroove.epg_light import EpgLight
from resources.modules.thegroove.thegroove_httpclient import ThegrooveHttpClient

try:
    from urllib.parse import quote as quoter
    from urllib.parse import unquote as unquoter
except ImportError:
    from urllib import quote as quoter
    from urllib import unquote as unquoter

logger = logging.getLogger(xbmcaddon.Addon().getAddonInfo('id'))

pDialog = xbmcgui.DialogProgressBG()
dDialog = xbmcgui.DialogProgress()

tg_client = ThegrooveHttpClient()


def get_local_version():
    version_file = os.path.join(xbmcaddon.Addon().getAddonInfo('path'), 'thegroove_version.json')
    logger.debug(version_file)
    try:
        with open(version_file, 'r', encoding='utf-8') as version_json:
            data = json.load(version_json)
            version = data["version"]
            version_json.close()
            logger.debug("local version: " + version)

            return version
    except Exception as e:
        if kodiutils.get_setting_as_bool("debug"):
            import traceback
            traceback.print_stack()
            logger.debug(e)
        return ""


def get_remote_version():
    global tg_client
    res = requests.get(tg_client.server_url + "zip/addon.xml")
    try:
        version = re.compile(r'<addon.*?version=\"([^\"]+)\"', re.MULTILINE).findall(res.text)[0]
    except:
        version = None

    logger.debug("remote version: " + version)

    return version


def version_tuple(v):
    return tuple(map(int, (v.split("."))))


def check_update():
    pDialog.create('Thegroove 360', 'Controllo Aggiornamenti')
    try:
        rv = get_remote_version()
        lv = get_local_version()
        pDialog.update(100, message='Completato')
        if rv and rv != lv:
            pDialog.close()
            dDialog.create(xbmcaddon.Addon().getAddonInfo('id'), "Aggiornamento In Corso")
            download_new_release(rv)
        else:
            pDialog.close()
            epg_logos_update()
            resolver_update(force=False)

    except:
        raise
    finally:
        try:
            pDialog.close()
            dDialog.close()
        except Exception as e:
            if kodiutils.get_setting_as_bool("debug"):
                import traceback
                traceback.print_stack()
                logger.debug(e)
            pass


def epg_logos_update():
    try:
        import threading
        if kodiutils.get_setting_as_bool("show_epg"):
            epg = EpgLight(True)
            th_epg = threading.Thread(target=epg.get_epg_file, name="epg_updater")
            th_epg.daemon = True
            th_epg.start()
            # th_epg.join()

        if kodiutils.get_setting_as_bool("show_logos"):
            epg = EpgLight(True)
            th_logo = threading.Thread(target=epg.set_logos(), name="logos_updater")
            th_logo.daemon = True
            th_logo.start()
            # th_logo.join()
    except:
        raise


def download_new_release(ver):
    global tg_client
    tag_name = xbmcaddon.Addon().getAddonInfo('id') + "-" + ver + ".zip"
    out_name = "plugin.video.thegroove360"
    logger.debug("Download release " + ver)
    res = requests.get(tg_client.server_url + "zip/" + out_name + "/" + tag_name)
    zip_temp = u'special://temp/%s.zip' % out_name
    xbmcvfs.delete(zip_temp)
    if sys.version_info[0] < 3:
        out_temp = xbmc.translatePath(zip_temp)
    else:
        out_temp = xbmcvfs.translatePath(zip_temp)
    total_length = res.headers.get('content-length', 0)
    if int(total_length) == 0:
        total_length = -1

    with open(out_temp, 'wb') as f:
        dl = 0
        total_length = float(float(total_length) / 1024)
        for data in res.iter_content(chunk_size=1024):
            dl += (len(data) / 1024)
            f.write(data)
            perc = int(dl * 100 / total_length)

            dDialog.update(perc, "Download " + str(dl) + "Kb di " + str(total_length) + "Kb")
        f.close()

    dDialog.update(0, "Aggiornamento Addon Alla versione " + tag_name)
    if sys.version_info[0] > 2:
        target_folder = xbmcvfs.translatePath(u'special://temp/')
    else:
        target_folder = xbmc.translatePath(u'special://temp/')

    try:
        logger.debug("Installazione " + tag_name)
        install_zip(out_temp, target_folder, dDialog, tag_name)
        version_file = os.path.join(xbmcaddon.Addon().getAddonInfo('path'), 'thegroove_version.json')
        with open(version_file, 'w') as json_file:
            json.dump({"version": ver}, json_file)

    except:
        raise


def install_zip(zipped_file, unpack_folder, dialog, tag_name):
    dest_dir = xbmcaddon.Addon().getAddonInfo('path')
    global tg_client
    # logger.debug(zipped_file)

    try:
        with zipfile.ZipFile(zipped_file, 'r') as zfile:
            tot = len(zfile.infolist())
            zfile.extractall(path=unpack_folder)
            zfile.close()
    except zipfile.BadZipfile:
        import io
        from urllib.request import urlopen
        try:
            out_name = "plugin.video.thegroove360"
            with urlopen(tg_client.server_url + "zip/" + out_name + "-" + tag_name + ".zip") as response:
                content = response.read()
                z = zipfile.ZipFile(io.BytesIO(content))
                z.extractall(path=unpack_folder)
                tot = len(z.infolist())
                z.close()
        except:
            raise
            # req = Request("http://127.0.0.1:43110/list/1Atp8zSnAXBKXGroQU8MeWvDdWcnyShW8B/zipaddon/" + tag_name)
            # content = urlopen(req).read()
            # raise

    os.remove(zipped_file)
    try:
        tmp_dir = glob(os.path.join(unpack_folder, 'plugin.video.thegroove360*'))[0]
    except:
        tmp_dir = None
        pass
    count = 0

    dev_folder = os.path.join(xbmcaddon.Addon().getAddonInfo('path'), '.git')

    if os.path.exists(dev_folder):
        if tmp_dir:
            shutil.rmtree(tmp_dir)
        return

    for root, dirs, files in os.walk(tmp_dir):
        dst_dir = root.replace(tmp_dir, dest_dir, 1)
        if not os.path.exists(dst_dir):
            os.makedirs(dst_dir)
        for file_ in files:
            perc = count * 100 / tot
            dialog.update(perc, "Aggiornamento Addon Alla versione " + tag_name)
            src_file = os.path.join(root, file_)
            dst_file = os.path.join(dst_dir, file_)
            if os.path.exists(dst_file):
                try:
                    if os.path.samefile(src_file, dst_file):
                        continue
                except AttributeError:
                    if os.stat(src_file) == os.stat(dst_file):
                        continue
                os.remove(dst_file)
            shutil.move(src_file, dst_dir)
            count += 1
    shutil.rmtree(tmp_dir)


def resolver_update(force=False):
    resolver = 'script.module.tg360resolver'
    version_file = os.path.join(xbmcaddon.Addon(resolver).getAddonInfo('path'), 'domains_version.json')
    vhash = ""
    if force:
        try:
            file_to_rem = pathlib.Path(version_file)
            file_to_rem.unlink()
        except Exception as E:
            print(E)
            import traceback
            traceback.print_stack()
            pass

    if os.path.exists(version_file):
        f = open(version_file, "r")
        data = json.loads(f.read())
        vhash = data["hash"]

    jfile = os.path.join(xbmcaddon.Addon().getAddonInfo('path'), 'resources', 'modules', 'thegroove', "token.json")
    with open(jfile, encoding='utf-8', errors='ignore') as json_data:
        minf = json.load(json_data, strict=False)
        server_url = minf["url"]

    cli = HttpClient()
    r = cli.get_request(server_url + "scripters/Resolver/update/version.json")
    if r.status_code == 200:
        with open(version_file, 'w+') as outfile:
            outfile.write(r.text)
            outfile.close()

    res = cli.get_request(server_url + "scripters/Resolver/update/update.php?hash=" + vhash)
    logger.debug(res.status_code)
    logger.debug(res.text)

    if res.status_code == 200:
        import threading
        import resolver_360
        try:
            th_domains = threading.Thread(target=resolver_360.update_domains, name="domains_updater",
                                          args=(res.json(),))
            th_domains.daemon = True
            th_domains.start()
        except Exception as E:
            import traceback
            traceback.print_stack()
            print(E)
