from unittest.mock import patch, ANY

import osmnx as ox
from django.conf import settings
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.core.exceptions import ObjectDoesNotExist
from recuperateur_reseau_viaire.models import Graph_viaire_ville_information, Ville, Rassemblement_ville
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


class creation_gvvi_formulaireTests(StaticLiveServerTestCase):

    selenium = None

    @classmethod
    def setUpClass(cls):
        """
        Le but de cette méthode est d'initialiser selenium avant le début des tests de la classe

        """
        super().setUpClass()
        cls.selenium = WebDriver()
        cls.selenium.implicitly_wait(10)

    @classmethod
    def tearDownClass(cls):
        """
        Le but de cette méthode est de fermer selenium à la fin des tests de la classe
        """
        cls.selenium.quit()
        super().tearDownClass()

    def setUp(self) -> None:
        """
        Le but de cette méthode est que selenium soit dans l'index du site à chaque test
        """
        self.selenium.get('%s%s' % (self.live_server_url, '/recuperateur_reseau_viaire/'))

    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.sauvegarde_graphique')
    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.lire_graphe')
    @patch('OSM_outils.OMSnx_enregistrement.OMSnx_enregistrement.recuperer_graphe_viaire_ville')
    def test_creation_une_instance_gvvi_simple(self, mock_recuperer_graphe_viaire_ville,
                                               mock_lire_graphe, mock_sauvegarde_graphique):
        """
        Cette méthode test si nous pouvons créer une nouvelle ligne Graph_viaire_ville_information depuis une base vide
        """
        nom_ville = "Vaudherland"
        # aller sur le formulaire de création de nouvelle ligne
        self.selenium.find_element(
            By.LINK_TEXT, "Ajout"
        ).click()
        self.assertTrue(self.selenium.current_url.endswith("/recuperateur_reseau_viaire/telecharge_liste_commune"))

        # remplir l'entrée texte avec un nom de ville
        entree_nom_ville = self.selenium.find_element(By.CSS_SELECTOR, "tr").find_element(By.CSS_SELECTOR, "input")
        entree_nom_ville.clear()
        entree_nom_ville.send_keys(nom_ville)

        # mock la récupération de graph pour faire croire qu'il est téléchargé depuis overpass mais est sur le pc
        # mock la sauvegarde pour ne pas sauvegarder le graph
        # mock lire_graph pour lire le fichier dans le dossier Data de Test
        mock_lire_graphe.side_effect = FileNotFoundError()
        mock_recuperer_graphe_viaire_ville.return_value = ox.load_graphml(settings.BASE_DIR.__str__() + "/recuperateur_reseau_viaire/Tests/Data/" + nom_ville + ".graphml")
        mock_recuperer_graphe_viaire_ville.return_value.name = nom_ville

        #valider le formulaire
        WebDriverWait(self.selenium, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='btn btn-success']")))
        entree_nom_ville.submit()

        #attendre la fin du calcul OSMnx_recuperation_graph_information en attendant l'affichage du titre
        WebDriverWait(self.selenium, 10).until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, "h1"), "Votre action a bien été enregistré"))

        #vérification bon titre
        self.assertEqual(self.selenium.find_element(By.CSS_SELECTOR, "h1").text, "Votre action a bien été enregistré")
        #appuyer sur le bouton de validation
        self.selenium.find_element(By.XPATH, "//a[@class='btn btn-success']").click()

        #vérifier que le graph a été sauvegardé une fois
        mock_sauvegarde_graphique.assert_called_once_with(ANY, nom_ville)

        #vérifier que l'on est retournée sur la page principale
        self.assertTrue(self.selenium.current_url.endswith("/recuperateur_reseau_viaire/telecharge_liste_commune"))
