'''Module proposant une implémentation d'une File MUABLE
   en utilisant une liste chaînée tete-fin sous forme objet
 
Sur notre exemple :
* L'AVANT de la File est la TETE de la liste chaînée (pour la suppression à coût CST)
* L'ARRIERE de la File est la FIN de la liste chaînée (pour l'insertion à coût CST)
 
Fonctions primitives
--------------------
CST : nouvelle_file() -> 'File'
CST : est_file_vide(f:'File') -> bool
CST : enfiler(f:'File', elt:'Element') -> None
CST : defiler(f:'File NON VIDE') -> 'Element'
CST : lire_avant(f:'File NON VIDE') -> 'Element'
 
'''

# Importation

from liste_chaine_objet_tete_fin import nouvelle_liste
from liste_chaine_objet_tete_fin import est_liste_vide
from liste_chaine_objet_tete_fin import inserer_fin
from liste_chaine_objet_tete_fin import supprimer_tete
from liste_chaine_objet_tete_fin import premier


# Fonctions primitives de la File

def nouvelle_file() -> 'File':
    """Renvoie une nouvelle File vide"""
    return nouvelle_liste()
     
def est_file_vide(f:'File') -> bool:
    """Prédicat qui renvoie True si la File est vide"""
    return est_liste_vide(f)
     
def enfiler(f:'File', elt:'Element') -> None:
    """Enfile elt dans la File"""
    inserer_fin(f, elt)  # L'insertion en fin d'une Liste Tete-Fin est à coût constant
     
def defiler(f:'File NON VIDE') -> 'Element':
    """Défile la file f"""
    return supprimer_tete(f)
     
def lire_avant(f:'File') -> 'Element':
    """Renvoie la valeur à l'avant de la File f"""
    return premier(f)
 
# Programme de test

if __name__ == '__main__':
    a = nouvelle_file()
    enfiler(a, 0)
    enfiler(a, 5)
    enfiler(a, 10)
    enfiler(a, 15)
     
    s = lire_avant(a)
    assert s == 0
     
    defiler(a)
    s = lire_avant(a)
    assert s == 5 
