import traceback, sys, game

functions = [
    'touche_appuyee',
    'initialise',
    'perdu',
    'trace_raquette',
    'teste_collision_raquette',
    'teste_collision_briques',
    'efface_brique',
    'deplace_balle'
]

def do_tests(ns):
    global_result = True
    for name in functions:
        if 'test_' + name in globals():
            print('\n======= Test de la fonction "' + name + '" :')
            if exists(name, ns):
                result = False
                try:
                    result = globals()['test_' + name](ns[name], ns)
                except Exception as exc:
                    traceback.print_exc(file=sys.stderr)
                global_result = global_result and result
                if result:
                    print('OK')
            else:
                global_result = False
    if global_result:
        print("\nRésultat : OK")
    else:
        print("\nRésultat : Erreur")

def exists(fn, ns):
    if fn in ns:
        return True
    else:
        print('Erreur : La fonction "' + fn + '"' + " n'existe pas")

def reset_state(ns):
    ns['x_balle'] = 50
    ns['y_balle'] = 94
    ns['d_x_balle'] = 1
    ns['d_y_balle'] = -1
    ns['x_raquette'] = 40
    ns['y_raquette'] = 95
    ns['l_raquette'] = 20

def test_touche_appuyee(touche_appuyee, ns):
    result = True
    reset_state(ns)
    touche_appuyee(39)
    if ns['x_raquette'] != 41:
        result = False
        print("Erreur : l'appui sur la touche 'flèche droite' ne fait pas se déplacer la raquette d'un pixel à droite")
    reset_state(ns)
    touche_appuyee(37)
    if ns['x_raquette'] != 39:
        result = False
        print("Erreur : l'appui sur la touche 'flèche gauche' ne fait pas se déplacer la raquette d'un pixel à gauche")
    return result

def test_initialise(initialise, ns):
    reset_state(ns)
    initialise()
    for x in range(0, 100):
        for y in range(20, 60):
            if game.get_pixel(x, y) != "":
                return True
    print("Erreur : aucune brique n'a été affichée entre les lignes 20 et 60")
    return False

def test_perdu(perdu, ns):
    reset_state(ns)
    ns['y_balle'] = 99
    ns['d_y_balle'] = 1
    if perdu():
        return True
    else:
        print("Erreur : avec y_balle=99 et d_y_balle=1, la partie devrait être perdue")
        return False

def test_trace_raquette(trace_raquette, ns):
    reset_state(ns)
    trace_raquette()
    ns['x_raquette'] = 70
    trace_raquette()
    for x in range(100):
        if 40 <= x < 60 and game.get_pixel(x, 95) != "":
            print("Erreur : la raquette n'a pas été éffacée")
            return False
        elif 70 <= x < 90 and game.get_pixel(x, 95) == "":
            print("Erreur : la raquette n'a pas tracée")
            return False
        elif not (40 <= x < 60) and not (70 <= x < 90) and game.get_pixel(x, 95) != "":
            print(x, game.get_pixel(x, 95))
            print("Erreur : la raquette n'a pas tracée au bon endroit")
            return False
    return True

def test_teste_collision_raquette(teste_collision_raquette, ns):
    reset_state(ns)
    print("Ce test n'est pas encore réalisé")
    return True

def test_teste_collision_briques(teste_collision_briques, ns):
    reset_state(ns)
    print("Ce test n'est pas encore réalisé")
    return True

def test_efface_brique(efface_brique, ns):
    reset_state(ns)
    print("Ce test n'est pas encore réalisé")
    return True

    ns['x_balle'] = 50
    ns['y_balle'] = 94
    ns['d_x_balle'] = 1
    ns['d_y_balle'] = -1

def test_deplace_balle(deplace_balle, ns):
    result = True

    reset_state(ns)
    deplace_balle()
    if ns['x_balle'] != 51 or ns['y_balle'] != 93:
        print("Erreur : la balle ne s'est pas déplacée correctement")
        result =  False

    reset_state(ns)
    ns['d_x_balle'] = -1
    ns['d_y_balle'] = 1
    deplace_balle()
    if ns['x_balle'] != 49 or ns['y_balle'] != 95:
        print("Erreur : la balle ne s'est pas déplacée correctement")
        result =  False

    reset_state(ns)
    ns['x_balle'] = 99
    ns['d_x_balle'] = 1
    deplace_balle()
    if ns['x_balle'] != 98 or ns['d_x_balle'] != -1:
        print("Erreur : la balle n'a pas rebondi correctement à droite")
        result =  False

    reset_state(ns)
    ns['x_balle'] = 0
    ns['d_x_balle'] = -1
    deplace_balle()
    if ns['x_balle'] != 1 or ns['d_x_balle'] != 1:
        print("Erreur : la balle n'a pas rebondi correctement à gauche")
        result =  False

    reset_state(ns)
    ns['y_balle'] = 0
    ns['d_y_balle'] = -1
    deplace_balle()
    if ns['y_balle'] != 1 or ns['d_y_balle'] != 1:
        print("Erreur : la balle n'a pas rebondi correctement en haut")
        result =  False

    reset_state(ns)
    ns['y_balle'] = 99
    ns['d_y_balle'] = 1
    deplace_balle()
    if ns['y_balle'] != 98 or ns['d_y_balle'] != -1:
        print("Erreur : la balle n'a pas rebondi correctement en bas")
        result =  False

    reset_state(ns)
    deplace_balle()
    deplace_balle()
    if game.get_pixel(51, 93) != "":
        print("Erreur : la balle n'a pas été effacée")
        result =  False
    if game.get_pixel(52, 92) == "":
        print("Erreur : la balle n'a pas été tracée")
        result =  False

    return result
