import os, sys, tempfile
import os; sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import outils

base = tempfile.mkdtemp()
site = os.path.join(base, "site"); os.makedirs(site)
hors = os.path.join(base, "secret.txt")
open(hors, "w").write("SECRET")

ok = 0; ko = 0
def v(cond, libelle):
    global ok, ko
    if cond: ok += 1; print("  ok   %s" % libelle)
    else: ko += 1; print("  ECHEC %s" % libelle)

print("-- écriture normale")
r, err = outils.executer(site, "ecrire_fichier", {"chemin": "assets/css/style.css", "contenu": "body{}\n"})
v(not err and os.path.isfile(os.path.join(site, "assets/css/style.css")), "sous-dossier créé : %s" % r)

print("-- tentatives d'évasion (doivent toutes être refusées)")
for mauvais in ["../secret.txt", "/etc/passwd", "assets/../../secret.txt",
                "....//....//secret.txt", "a\\..\\b.html", "assets/css/../../../x.html", "a/b/../../../secret.txt", "/../../secret.txt"]:
    r, err = outils.executer(site, "ecrire_fichier", {"chemin": mauvais, "contenu": "X"})
    v(err, "refusé %-28r -> %s" % (mauvais, r[:45]))
v(open(hors).read() == "SECRET", "le fichier hors périmètre est intact")

print("-- lien symbolique pointant dehors")
os.symlink(base, os.path.join(site, "evasion"))
r, err = outils.executer(site, "ecrire_fichier", {"chemin": "evasion/secret.txt", "contenu": "X"})
v(err, "lien symbolique refusé -> %s" % r[:45])
v(open(hors).read() == "SECRET", "toujours intact après le lien symbolique")

print("-- extensions")
for ext, attendu_err in [(".php", False), (".htaccess", False), (".py", False),
                         (".jpg", True), (".woff2", True), ("", True), (".sh", True)]:
    nom = ("f" + ext) if ext else "sansext"
    if ext == ".htaccess": nom = ".htaccess"
    r, err = outils.executer(site, "ecrire_fichier", {"chemin": nom, "contenu": "x"})
    v(err == attendu_err, "%-12s err=%s (attendu %s)" % (nom, err, attendu_err))

print("-- taille")
import config
r, err = outils.executer(site, "ecrire_fichier", {"chemin": "gros.html", "contenu": "x" * (config.MAX_OCTETS_FICHIER + 1)})
v(err, "fichier trop gros refusé")

print("-- lecture / liste / terminer")
r, err = outils.executer(site, "lire_fichier", {"chemin": "assets/css/style.css"})
v(not err and r == "body{}\n", "relecture fidèle")
r, err = outils.executer(site, "lire_fichier", {"chemin": "inexistant.html"})
v(err, "lecture d'un absent -> erreur douce")
r, err = outils.executer(site, "lister_fichiers", {})
v(not err and "assets/css/style.css" in r, "liste")
r, err = outils.executer(site, "terminer", {"resume": "fini"})
v(not err, "terminer")
r, err = outils.executer(site, "inconnu", {})
v(err, "outil inconnu -> erreur douce")

print("-- entrées malformées (ne doivent jamais lever)")
for entree in [{}, {"chemin": None, "contenu": "x"}, {"chemin": "a.html", "contenu": 42},
               {"chemin": "", "contenu": "x"}, {"chemin": "   ", "contenu": "x"}]:
    try:
        r, err = outils.executer(site, "ecrire_fichier", entree)
        v(err, "refusé proprement %r" % (entree,))
    except Exception as e:
        v(False, "a levé %r sur %r" % (e, entree))

print("\n%d ok, %d échecs" % (ok, ko))
sys.exit(1 if ko else 0)
