"""
/********************************** *****************************************
 tools
                                 A QGIS plugin
 wide area mapping
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2022-01-01
        git sha              : $Format:%H$
        copyright            : (C) 2022 by CISS TDI GmbH
        email                :
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
import inspect
import time
import requests
import os
from PyQt5.QtCore import QUrl, QEventLoop
from PyQt5.QtNetwork import QNetworkRequest
from qgis.core import QgsNetworkAccessManager
from requests import Session


def replace_ampersands(p_base: str) -> str:
    """
    replaces & with &#038; in the  given base string

    :param p_base: base string
    :return: None
    """
    if len(p_base) == 0:
        return ""

    s_amp = 0
    while p_base.find("&", s_amp) != -1:
        s_amp = p_base.find("&", s_amp)

        # check if the following char is #
        if p_base[s_amp + 1] != "#":
            p_base = p_base[:s_amp + 1] + "#038;" + p_base[s_amp + 1:]
        s_amp += 4
    return p_base


def get_class_from_frame(fr):
    args, _, _, value_dict = inspect.getargvalues(fr)
    # we check the first parameter for the frame function is
    # named 'self'
    if len(args) and args[0] == 'self':
        # in that case, 'self' will be referenced in value_dict
        instance = value_dict.get('self', None)
        if instance:
            # return its class
            return getattr(instance, '__class__', None)
    # return None otherwise
    return None


def get_plugin_dir() -> str:
    """
    returns the plugin dir
    """
    full_path = os.path.realpath(__file__)
    plugin_dir = os.path.dirname(full_path)[0:-4]

    if os.path.isdir(plugin_dir):
        return plugin_dir
    return ""


def get_base_root_dir() -> str:
    """
    returns the base root dir
    Normally its a folder in documents of the user
    """
    root_dir = "root_dir"
    if not os.path.isdir(root_dir):
        os.mkdir(root_dir)
    return os.path.expanduser("~") + "\\Documents\\" + root_dir


def get_module_name(module: str) -> str:
    m = module.split(".")
    return m[len(m) - 1]


def get_external_ip_address() -> str:
    """
    queries the myip dnsomatic website an extract the ip
    :return: ip address
    """
    while True:
        r = requests.request('GET', 'http://myip.dnsomatic.com')
        if r.status_code == 200:
            return r.text
        else:
            time.sleep(0.2)


def check_internet_connection() -> bool:
    """
    check if the client is conected to the internet
    """
    try:
        s = Session()
        s.get(url="https://www.google.de")
        return True
    except:
        return False


def check_internet_qgis() -> bool:
    """
    check internet connection with qgis
    """
    try:
        def on_finish():
            loop.quit()

        request = QNetworkRequest()
        request.setUrl(QUrl("https://www.google.de"))
        manager = QgsNetworkAccessManager.instance()
        reply = manager.get(request)
        reply.setParent(None)
        loop = QEventLoop()
        reply.finished.connect(on_finish)
        loop.exec_()

        status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
        if status == 301:
            redirectUrl = reply.attribute(request.RedirectionTargetAttribute)
            request = QNetworkRequest()
            request.setUrl(redirectUrl)
            manager = QgsNetworkAccessManager.instance()

            reply = manager.get(request)
            reply.setParent(None)

            loop = QEventLoop()
            reply.finished.connect(on_finish)
            loop.exec_()
    except:
        return False
    return True


def download_over_qt(dlURL, LokFileName):
    # QGIS3:  funktioniert unter QGIS 3.x recht zuverlässig auch auf "eingeschränktem Rechner"
    # - nutzt die Proxyeinstellungen von QGIS
    # - funktioniert in QGIS selbst auch über HTTPS (es wird durch QGIS eiun Abfragefenster geöffnet)
    # - bei extrem großen Dateien (z.B. 500MBYte) crasht es bei ReadAll()

    # QGIS2:  funktioniert unter QGIS 2.x innerhalb von QGIS aktuell recht zuverlässig auch auf "eingeschränktem Rechner"
    #         außerhalb hängt sich der Code auf "eingeschräktem Rechner" auf und bringt dann auch kein Ergebnis
    #         Normalrechner funktioniert es
    def WriteFile(LokFileName, content):
        # 1. Ziel löschen, wenn existent
        if os.path.exists(LokFileName):
            os.remove(LokFileName)
        out = open(LokFileName, 'wb')
        out.write(content)
        out.close()

    def onfinish():
        WriteFile(LokFileName, reply.readAll())
        loop.quit()

    # 2. Download
    request = QNetworkRequest()
    request.setUrl(QUrl(dlURL))
    manager = QgsNetworkAccessManager.instance()

    reply = manager.get(request)
    reply.setParent(None)

    loop = QEventLoop()
    reply.finished.connect(onfinish)
    loop.exec_()

    # Wiederholung bei redirekt (13.08.18 Thüringen leitet an HTTPS weiter)
    status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
    if status == 301:
        redirectUrl = reply.attribute(request.RedirectionTargetAttribute)
        request = QNetworkRequest()
        request.setUrl(redirectUrl)
        manager = QgsNetworkAccessManager.instance()

        reply = manager.get(request)
        reply.setParent(None)

        loop = QEventLoop()
        reply.finished.connect(onfinish)
        loop.exec_()

    if os.path.exists(LokFileName):
        return os.path.getsize(LokFileName), reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
    else:
        return None, reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
