# (c) Didier  LECLERC 2024 CHARGE D'ETUDES GEOMATIQUES MTE-MCTRCT/SG/DNUM/MSP/DS/GSG/PMIRG Site de Rouen
# créé sept 2024 

import requests
import os
from time import time

class GeoIdeDistribution :
    """Class GeoIdeDistribution.
    Cette classe permet d'interroger les géoservices de la Géoplateforme, 

        >>> GeoIdeDistribution(URL_API_GPF)

    Attributes
    ----------
    Le constructeur doit avoir comme paramètres l'url de l'APi de la Géoplateforme

    Exemple d'utilisation
    # Paramètres entrée
    URL_API_GPF        = "https://data.geopf.fr//telechargement"
    
    # Exemple d'utilisation de la classe GeoIdeDistribution pour lister les ressources (GetCapabilities)
    instanceGPF = GeoIdeDistribution(URL_API_GPF)
    ret         = instanceGPF.get_resources()
    """
    
    def __init__(self, _URL_API_GPF, _URL_API_GPF_PRIVATE, _mValueLoginGPF, _HTTP_PROXY_GPF, _HTTPS_PROXY_GPF, _HTTP_PROXY_GI_DISTRIBUTION, _HTTPS_PROXY_GI_DISTRIBUTION):
        # Déclaration des proxy
        self._HTTP_PROXY_GPF  = _HTTP_PROXY_GPF 
        self._HTTPS_PROXY_GPF = _HTTPS_PROXY_GPF
        self._HTTP_PROXY_GI_DISTRIBUTION  = _HTTP_PROXY_GI_DISTRIBUTION
        self._HTTPS_PROXY_GI_DISTRIBUTION = _HTTPS_PROXY_GI_DISTRIBUTION
        self._mValueLoginGPF  = _mValueLoginGPF
        
        os.environ["HTTP_PROXY"]  = _HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = _HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = _HTTP_PROXY_GPF
        os.environ["https_proxy"] = _HTTPS_PROXY_GPF

        _getCapabilities = "/capabilities"
        _getResource     = "/resource"
        _getDownload     = "/download"
        #
        self.url_api_getCapabilities = _URL_API_GPF + _getCapabilities
        self.url_api_getResource     = _URL_API_GPF + _getResource
        self.url_api_getDownload     = _URL_API_GPF + _getDownload

        self.url_api_private_getCapabilities = _URL_API_GPF_PRIVATE + _getCapabilities
                  
    def get_capabilities(self, _nb_occurence = 50, _nb_page = 1, _lang = 'FR', _zone = None, _format = None, _dateFrom = None, _dateTo = None):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF
        """Liste les ressources (GetCapabilities)."""
        url           = f"{self.url_api_getCapabilities}?lang=" + _lang  + "&page=" + str(_nb_page) + "&limit=" + str(_nb_occurence)
        #print("get_capabilities ", _lang , _zone , _format) 
        url           += "" if (_zone == None or _zone == '')     else "&zone="   + str(_zone) 
        url           += "" if (_format == None or _format == '') else "&format=" + str(_format)
        if not (_dateFrom == None or _dateFrom == '') :
           url        += "&editionDateFrom=" + str(_dateFrom) + "&editionDateTo=" + str(_dateTo)
         
        #print("get_capabilities ",url)
        
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None

        return retGet

    def get_capabilities_private(self, _nb_occurence = 50, _nb_page = 1, _lang = 'FR', _zone = None, _format = None, _dateFrom = None, _dateTo = None):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF
        """Liste les ressources (GetCapabilities)."""
        url           = f"{self.url_api_private_getCapabilities}?apikey=" + self._mValueLoginGPF + "&lang=" + _lang  + "&page=" + str(_nb_page) + "&limit=" + str(_nb_occurence)
        #print("get_capabilities ", _lang , _zone , _format) 
        url           += "" if (_zone == None or _zone == '')     else "&zone="   + str(_zone) 
        url           += "" if (_format == None or _format == '') else "&format=" + str(_format) 
        if not (_dateFrom == None or _dateFrom == '') :
           url        += "&editionDateFrom=" + str(_dateFrom) + "&editionDateTo=" + str(_dateTo)
        #print("_dateFrom", _dateFrom)           
        #print("get_capabilities ",url)
        
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None

        return retGet

    def get_resources(self, _resourceName):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF
        """Lister dossiers d'une ressource (GetResource)."""
        url          = f"{self.url_api_getResource}/{_resourceName}"
        retGet       = requests.get(url)
        return retGet
        
    def get_resources_directe(self, _resourceName, _entry = 1, _entry_en_Cours = 50, _lang = 'FR', _zone = None, _format = None, _dateFrom = None, _dateTo = None):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF

        """Lister dossiers d'une ressource (GetResource)."""
        _page           = _entry          if _entry != 1           else _entry
        _entry_en_Cours = _entry_en_Cours if _entry_en_Cours != 50 else _entry_en_Cours
        url          = f"{_resourceName}?page=" + str(_page) + "&limit=" + str(_entry_en_Cours)
        url           += "" if (_zone == None or _zone == '')     else "&zone="   + str(_zone) 
        url           += "" if (_format == None or _format == '') else "&format=" + str(_format) 
        if not (_dateFrom == None or _dateFrom == '') :
           url        += "&editionDateFrom=" + str(_dateFrom) + "&editionDateTo=" + str(_dateTo)
        #print("_dateFrom", _dateFrom)           
        #print("get_resources_directe ",url, "\n")
                
        retGet       = requests.get(url)
        return retGet

    def get_resources_directe_private(self, _resourceName, _entry = 1, _entry_en_Cours = 50, _lang = 'FR', _zone = None, _format = None, _dateFrom = None, _dateTo = None):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF

        """Lister dossiers d'une ressource (GetResource)."""
        _page           = _entry          if _entry != 1           else _entry
        _entry_en_Cours = _entry_en_Cours if _entry_en_Cours != 50 else _entry_en_Cours
        url          = f"{_resourceName}?apikey=" + self._mValueLoginGPF + "&page=" + str(_page) + "&limit=" + str(_entry_en_Cours)
        url           += "" if (_zone == None or _zone == '')     else "&zone="   + str(_zone) 
        url           += "" if (_format == None or _format == '') else "&format=" + str(_format) 
        if not (_dateFrom == None or _dateFrom == '') :
           url        += "&editionDateFrom=" + str(_dateFrom) + "&editionDateTo=" + str(_dateTo)
        #print("_dateFrom", _dateFrom)           
        #print("get_resources_directe_private ",url, "\n")
                
        retGet       = requests.get(url)
        return retGet

    def get_subResources(self, _resourceName, _subresourceName):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF
        """Lister les fichiers d'un sous-dossier d'une ressource (GetSubResource)."""
        url          = f"{self.url_api_getResource}/{_resourceName}/{_subresourceName}"
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None

        return retGet

    def get_subResources_directe(self, _subresourceName):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF
        """Lister les fichiers d'un sous-dossier d'une ressource (GetSubResource)."""
        url          = f"{_subresourceName}"
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None

        return retGet
                
    def get_subResources_directe_private(self, _subresourceName):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF
        """Lister les fichiers d'un sous-dossier d'une ressource (GetSubResource)."""

        url          = f"{_subresourceName}?apikey=" + self._mValueLoginGPF
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None

        return retGet

    def get_donwload(self, _resourceName, _subresourceName, _fileName):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF
        """Télécharger un fichier (Download)."""
        url          = f"{self.url_api_getDownload}/{_resourceName}/{_subresourceName}/{_fileName}"
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None
        return retGet     

    def get_donwload_GI_Distribution(self, _file_url_a_telecharger, _local_file_destination, _geoide_distrib_http_user, _geoide_distrib_http_pass, _geoide_distrib_rate) :
        """Télécharger un fichier (Download) depusi GI Distribution."""
        """ EXEMPLE CURL
        set URLGI="https://geoide-distribution.e2.rie.gouv.fr/02-BDO-RVB/MONODALLES_DEPARTEMENTALES/BDO_MND_0M50_TIF_LAMB93_D075-ED21.7z.001"
        set FILEDESTI="BDO_MND_0M50_TIF_LAMB93_D075-ED21.7z.001" 
        curl -L %URLGI% -u "geoide:1!kLp%%98" -o %FILEDESTI%

        _file_url_a_telecharger = "https://geoide-distribution.e2.rie.gouv.fr/02-BDO-RVB/MONODALLES_DEPARTEMENTALES/BDO_MND_0M50_TIF_LAMB93_D075-ED21.7z.001"
        _local_file_destination = "C:/Users/didier.leclerc/AppData/Roaming/QGIS/QGIS3/profiles/default/python/plugins/qgidistribution/admingenerale/" + os.path.basename( _file_url_a_telecharger ) 
        _geoide_distrib_http_user = "xxxx"
        _geoide_distrib_http_pass = r"yyyyyyyy"
        """
        
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GI_DISTRIBUTION
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GI_DISTRIBUTION
        os.environ["http_proxy"]  = self._HTTP_PROXY_GI_DISTRIBUTION
        os.environ["https_proxy"] = self._HTTPS_PROXY_GI_DISTRIBUTION

        try:
             # Envoi de la requête avec authentification
             response = requests.get(_file_url_a_telecharger, auth=(_geoide_distrib_http_user, _geoide_distrib_http_pass), stream=True)
             
             # Vérification du statut HTTP
             response.raise_for_status()

             # Écriture du contenu dans un fichier local
             with open(_local_file_destination, "wb") as file:
                 for chunk in response.iter_content(chunk_size=_geoide_distrib_rate):
                     if chunk:  # Filtrage des chunks vides
                         file.write(chunk)

             print(f"Fichier téléchargé avec succès dans '{_local_file_destination}'.")

        except requests.exceptions.RequestException as e:
             print(f"Erreur lors du téléchargement : {e}")

        return      

    def Good_get_download_GPF(self, file_url_a_telecharger, local_file_destination, geoide_distrib_rate):
         os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
         os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
         os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
         os.environ["https_proxy"] = self._HTTPS_PROXY_GPF

         try:
              # Envoi de la requête avec authentification et téléchargement par chunks
              response = requests.get(file_url_a_telecharger, stream=True)
              
              # Vérification du statut HTTP
              response.raise_for_status()

              # Écriture dans le fichier local
              with open(local_file_destination, "wb") as file:
                  for chunk in response.iter_content(chunk_size=geoide_distrib_rate):
                      if chunk:  # Filtrer les chunks vides
                          file.write(chunk)

              print(f"Fichier téléchargé avec succès dans '{local_file_destination}'.")

         except requests.exceptions.RequestException as e:
              print(f"Erreur lors du téléchargement : {e}")

         return      

    def get_download_GPF(self, file_url_a_telecharger, local_file_destination, geoide_distrib_rate):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF

        # Requête initiale pour obtenir la taille du fichier
        response = requests.head(file_url_a_telecharger)
        file_size = int(response.headers.get('Content-Length', 0))

        # Téléchargement par morceaux
        chunk_size = 1024 * 1024  # 1 MB
        downloaded = 0  # Taille téléchargée
        start_time = time()  # Pour calculer le temps écoulé

        with requests.get(file_url_a_telecharger, stream=True) as r, open(local_file_destination, "wb") as f:
            for chunk in r.iter_content(chunk_size=chunk_size):
                if chunk:
                   f.write(chunk)
                   downloaded += len(chunk)

                   # Barre de progression
                   percent = (downloaded / file_size) * 100
                   elapsed_time = time() - start_time
                   speed = downloaded / elapsed_time / (1024 * 1024)  # Vitesse en MB/s

                   print(f"\rTéléchargé : {percent:.2f}% ({downloaded / (1024 * 1024):.2f} MB / {file_size / (1024 * 1024):.2f} MB) "
                         f"à {speed:.2f} MB/s", end="")

        print("\nTéléchargement terminé.")
        return      

    def get_donwload_directe(self, _fileName):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF

        """Télécharger un fichier (Download)."""
        url          = f"{_fileName}"
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None
        return retGet  
        
    def get_donwload_directe_private(self, _fileName):
        os.environ["HTTP_PROXY"]  = self._HTTP_PROXY_GPF
        os.environ["HTTPS_PROXY"] = self._HTTPS_PROXY_GPF
        os.environ["http_proxy"]  = self._HTTP_PROXY_GPF
        os.environ["https_proxy"] = self._HTTPS_PROXY_GPF

        """Télécharger un fichier (Download)."""
        url          = f"{_fileName}?apikey=" + self._mValueLoginGPF
        try:
           retGet = requests.get(url)
              
           # Vérifier le statut de la réponse
           if retGet.status_code != 200:
              print(f"Erreur : {response.status_code}")

        except :
           print("Erreur : Problème avec le proxy.")
           retGet = None
        return retGet  

__all__ = ['GeoIdeDistribution']
