# -*- coding: utf-8 -*-

"""
This file contains all of tests realized on the modele module.
@author: Felix Molina
@version: 1.0
"""

import os

import modele


def unitTest_participantDataVerification():
    """
    This function tests if the verification of participant data is right with the participantDataVerification method.
    It purpose three tests : the first returns an error because a wrong participantData list has been entered.
    The second returns true because the list is right. The third returns an error because the participant is already in the database.
    @return: just a message showing the results of tests.
    """
    print("------------------------\n"
          "@param participantData\n"
          "@type participantData: list [id: int, lastName: str, firstName: str, birthDate: str, gender: char, weight: int, club: str, level: int, height: int (or height = '')]")
    print("------------------------\nPremier test : erreur sur la date.")
    participantData = [-1, "sonNom", "sonPrenom", "01-01-1990", "M", 50, "INT", 0, ""]
    print("participantData = " + str(participantData))
    print("Ce test doit renvoyer False.\nResultat : " + str(database.participantDataVerification(participantData)))

    print("------------------------\nSecond test : liste correcte.")
    participantData = [-1, "sonNom", "sonPrenom", "01/01/1990", "M", 50, "INT", 0, ""]
    print("participantData = " + str(participantData))
    print("Ce test doit renvoyer True.\nResultat : " + str(database.participantDataVerification(participantData)))

    print("------------------------\nPour les besoins du troisieme test, les donnees precedentes sont enregistrees dans la base de donnees.")
    print("Entree dans la base : " + str(participantData))
    database.addParticipant(participantData)

    print("------------------------\nTroisieme test : liste correcte mais deja presente dans la base de donnees.")
    participantData = [-1, "sonNom", "sonPrenom", "01/01/1990", "M", 50, "INT", 0, ""]
    print("participantData = " + str(participantData))
    print("Ce test doit renvoyer False.\nResultat : " + str(database.participantDataVerification(participantData)))

    database.deleteParticipant(1)
    print("------------------------\n"
          "Fin de test.\n"
          "------------------------")


def unitTest_categoryDataVerification():
    """
    This function tests if the verification of categorie data is right with the categorieDataVerification method.
    It purpose four tests : the first returns an error because a wrong categorieData list has been entered.
    The second returns true because the list is right.
    The third and the fourth return an error because the categorie is already in the database or a part of the range of the categorie is already in the database.
    @return: just a message showing the result of tests.
    """
    print("------------------------\n"
          "@param categorieData\n"
          "@type categorieData: list [id: int, type: int, minValue: int, maxValue: int]")
    print("------------------------\n"
          "Premier test : erreur sur la valeur inferieure.")
    categorieData = [-1, 1, -1, 6]
    print ("categorieData = " + str(categorieData) + " (type = 1 = Poids)")
    print ("Ce test doit renvoyer False.\nResultat : " + str(database.categorieDataVerification(categorieData)))

    print("------------------------\n"
          "Second test : liste correcte.")
    categorieData = [-1, 1, 50, 55]
    print ("categorieData = " + str(categorieData) + " (type = 1 = Poids)")
    print ("Ce test doit renvoyer True.\n"
           "Resultat : " + str(database.categorieDataVerification(categorieData)))

    print(
    "------------------------\n"
    "Pour les besoins du troisieme test, les donnees precedentes sont enregistrees dans la base de donnees.")
    print("Entree dans la base : " + str(categorieData))
    database.addCategorie(categorieData)

    print("------------------------\n"
          "Troisieme test : liste correcte mais deja presente dans la base de donnees.")
    categorieData = [-1, 1, 50, 55]
    print ("categorieData = " + str(categorieData) + " (type = 1 = Poids)")
    print ("Ce test doit renvoyer False.\n"
           "Resultat : " + str(database.categorieDataVerification(categorieData)))

    print("------------------------\n"
          "Quatrieme test : liste correcte mais la categorie est a cheval avec la plage d'une categorie dans la base de donnees.")
    categorieData = [-1, 1, 48, 52]
    print ("categorieData = " + str(categorieData) + " (type = 1 = Poids)")
    print ("Ce test doit renvoyer False.\nResultat : " + str(database.categorieDataVerification(categorieData)))

    database.deleteCategorie(1)
    print("------------------------\n"
          "Fin de test.\n"
          "------------------------")


def unitTest_has_exception_linked_to():
    """
    This function tests if a participant is linked to an exception.
    It purpose two tests : the first returns false because any participant is linked to an exception.
    The second returns true because there is an exception for a participant.
    @return: just a message showing the result of tests.
    """
    print("------------------------\n"
          "@param idParticipant\n"
          "@type idParticipant: int")
    print("------------------------\n"
          "Premier test : pas d'exception liee.")
    idParticipant = 1
    print ("idParticipant = " + str(idParticipant))
    print ("Ce test doit renvoyer False.\n"
           "Resultat : " + str(database.has_exception_linked_to(idParticipant)))

    print(
        "------------------------\n"
        "Pour les besoins du second test, les donnees d'un participant et d'une exception sont enregistrees dans la base de donnees.")
    participantData = [-1, "sonNom", "sonPrenom", "01-01-1990", "M", 50, "INT", 0, ""]
    print("Entree dans la base : " + str(participantData))
    database.addCategorie(participantData)

    print("En realite, lors de l'ajout d'un nouveau participant, la base de donnees se charge de lui attribuer un id (incremente automatiquement).\n"
          "Donc ici l'id du participant ajoute sera 1 car c'est le seul.")
    print("Une exception est definie :\n"
          "@param exceptionData\n"
          "@type exceptionData: list [id: int, idParticipant: int, type: int, minValue: int, maxValue: int]")
    exceptionData = [-1, 1, 1, 70, 80]
    print("Entree dans la base : " + str(exceptionData))
    database.addException(exceptionData)

    print("------------------------\n"
          "Second test : exception liee.")
    idParticipant = 1
    print ("idParticipant = " + str(idParticipant))
    print ("Ce test doit renvoyer True.\n"
           "Resultat : " + str(database.has_exception_linked_to(idParticipant)))

    print("------------------------\n"
          "Fin de test.\n"
          "------------------------")

def unitTest_loadASave():
    """
    This function tests the loading method of the object.
    There are three tests. The first takes a path to basic text file and try to load it like a sql file.
    The second takes a wrong path.
    The thrid takes a right path to a text file containing the right syntax of a sql code.
    @return: just a message showing the result of tests.
    """
    print("------------------------\n"
          "@param pathFileName\n"
          "@type pathFileName: str")
    print("------------------------\n"
          "Pour les tests, nous creons 2 fichiers '.fim' (qui sont en realite similaires a des fichiers txt).\n"
          "Le premier contiendra du texte, une phrase par exemple.\n"
          "Le second contiendra la syntaxe requise pour que le fichier soit interprete comme une fichier sql produit par le gestionnaire de combat, c'est-a-dire :\n"
          "- premiere ligne du fichier : '--gestionnaire_combat_v3'\n"
          "- les deux lignes suivantes : 'BEGIN TRANSACTION;' et 'COMMIT;'.\n"
          "Evidememt, entre BEGIN TRANSACTION et COMMIT, il peut ne rien avoir ou alors il faut du code sql sinon la methode renverra une erreur.")

    print("------------------------\n"
          "Creation des fichiers 'unit-test-loading_1.fim' et 'unit-test-loading_2.fim'")
    file1 = open("unit-test-loading_1.fim", 'w')
    file2 = open("unit-test-loading_2.fim", 'w')
    print("Dans 'unit-test-loading_1.fim', nous ecrivons une pharse :\n"
          "Ce fichier est cre pour le test n°1 de la methode 'loadASave' du module MODELE.\n")
    file1.write("Ce fichier est cre pour le test n°1 de la methode 'loadASave' du module MODELE.")
    print("Dans 'unit-test-loading_2.fim', nous ecrivons (sur 3 lignes) :\n"
          "--gestionnaire_combat_v3\n"
          "BEGIN TRANSACTION;\n"
          "COMMIT;")
    file2.write("--gestionnaire_combat_v3\nBEGIN TRANSACTION;\nCOMMIT;\n")
    file1.close()
    file2.close()

    print("------------------------\n"
          "Premier test : fichier existant mais le contenu n'est pas au format requis.")
    pathFileName = "unit-test-loading_1.fim"
    print ("pathFileName = " + str(pathFileName))
    print ("Ce test doit renvoyer False.\n"
           "Resultat : " + str(database.loadASave(pathFileName)))

    print("------------------------\n"
          "Second test : fichier non existant.")
    pathFileName = "unit-test-loading_3.fim"
    print ("pathFileName = " + str(pathFileName))
    print ("Ce test doit renvoyer False.\n"
           "Resultat : " + str(database.loadASave(pathFileName)))

    print("------------------------\n"
          "Troisieme test : fichier existant contenant le necessaire pour son chargement en tant que code sql du gestionnaire de combats.")
    pathFileName = "unit-test-loading_2.fim"
    print ("pathFileName = " + str(pathFileName))
    print ("Ce test doit renvoyer True.\n"
           "Resultat : " + str(database.loadASave(pathFileName)))

    print("------------------------\n"
          "Fin de test.\n"
          "------------------------")


def testInterface():
    """
    Interface for tests.
    @return: console interface
    """
    print("------------------------\n"
          "Module de test du module MODELE\n"
          "------------------------\n")

    answer = 0

    # Creation des tables pour les tests.
    database.newMeetingDatabase()

    while True:
        print("------------------------\n"
              "Menu\n"
              "------------------------\n"
              "Selectionnez la methode a tester :\n"
              "1 - Tests de verification des donnees d'un participant\n"
              "2 - Tests de verification des donnees d'une categorie\n"
              "3 - Tests pour savoir si un participant a une exception qui lui est associee\n"
              "4 - Tests pour les chargements des sauvegardes\n"
              "5 - Quitter")

        try:
            answer = int(input("Entrez le chiffre correspondant :"))
        except (Exception, NameError):
            answer = 0

        if answer == 1:
            unitTest_participantDataVerification()
        elif answer == 2:
            unitTest_categoryDataVerification()
        elif answer == 3:
            unitTest_has_exception_linked_to()
        elif answer == 4:
            unitTest_loadASave()
        elif answer == 5:
            database.closeDatabase()
            break

        os.system("Pause")


# Initialisation de l'objet database pour les tests.
    global database
    database = modele.Modele()
    """@var: the MODELE object => the database"""

testInterface()
