# jukebox.py

import cfg  # simuler var globales, http://effbot.org/pyfaq/how-do-i-share-global-variables-across-modules.htm

# TODO : faire un fichier bash qui crée des situations inattendues
#        avant le démarrage de jukebox
# logging : https://docs.python.org/2/library/logging.html
# hotkeys : https://nitratine.net/blog/post/how-to-make-hotkeys-in-python/
# 1. dossier /m vide
# 2. sous-dossiers absents
# 3. espace libre très bas
# TODO : remettre à plat les fichiers de données en lecture seule,
#        et les fichiers de configuration système et utilisateur
#
import inc.infos as infos

from inc.inputkiz import input_seq

import inc.mpc as mpc
# import inc.start_stop as start_stop

import mod.aba as aba
import mod.commun as commun
# import mod.juk as juk       # accueil placé dans modules
# import mod.rec as rec
import mod.mtn as mtn
import mod.rad as rad
import mod.zik as zik

NOM_APPLI "Xavbox 2020"

def automate_jk(list_commands):
    """ automatiser les commandes """
    # ex : lancer RTL au démarrage avec les arguments 1 1 66
    #       1 reprend la radio
    #       1 lance le groupe 1
    #      66 reprend la radio
    mnu_commun cfg.dic_menus["commun"]

    for choix in list_commands:
        menu_module cfg.dic_menus[infos.ini_get("py_current_module""juk")]
        infos.m_g("automate : " choix)

        # menu commun
        if choix in mnu_commun.keys():
            une_commandedescription mnu_commun.get(choix)
            commande(choixune_commandedescription)

        # menu module
        elif choix in menu_module.keys():
            une_commandedescription menu_module.get(choix)
            commande(choixune_commandedescription)

            if infos.ini_get("py_current_module""juk") == "juk":
                nouveauMod cfg.mnu_juk_activer.get(choix)
                infos.ini_set("py_current_module"nouveauMod)
                infos.m_g("inp_loop, module " infos.ini_get("py_current_module""juk"))

        # mauvaise séquence (bipper ?)
        else:
            arr_msg = ["""Séquence de touches " choix " inconnue pour " infos.ini_get("py_current_module""juk")]
            infos.pdrNew(arr_msg)


def commande(choixune_commandedescription):
    """ Lance la commande pour 'appareil demandé """
    mnu_commun cfg.mnu_commun
    menu_module cfg.dic_menus[infos.ini_get("py_current_module""juk")]

    if choix in mnu_commun.keys():
        # lancer commande
        mnu_commun.get(choix)[0]()
    elif choix in menu_module.keys():
        menu_module.get(choix)[0]()


def inp_loop():
    """ Choix clavier utilisateur en fonction de l'appareil en cours """
    mnu_commun cfg.dic_menus["commun"]

    def la_les_touches(choix1):
        lc len(choix1)
        if lc == 1:
            return "la touche "
        elif lc 1:
            return "les touches "

    def a_la_les_touches(choix1):
        lc len(choix1)
        c2 choix1.replace(".""point ")
        c2 c2.replace("*""étoile ")
        if lc == 1:
            return "à la touche " c2
        elif lc 1:
            return "aux touches " c2

    while True:
        idx_menu infos.ini_get("py_current_module""juk")
        menu_module cfg.dic_menus[idx_menu]
        choix input_seq()  # entrer une touche ou combinaison de touches

        # fin mode consultation avec "12"
        # if choix == "12":
            # if infos.ini_get("mode_apprentissage", "off") == "off":
                # infos.ini_set("mode_apprentissage", "on")
                # msg = "mode apprentissage activé, " + \
                    # "tapez une touche ou une séquences de touches, " + \
                    # "pour connaître sa fonction, " + \
                    # "tapez 12 pour repasser en mode commande"
            # else:
                # infos.ini_set("mode_apprentissage", "off")
                # msg = "les commandes sont de nouveau actives"
            # infos.pdrNew(msg)


        if choix in ".":  # interrompt énoncé vocal en cours, on kille dans tous les cas, pas besoin de vérifier si un message est en cours de lecture
            import inc.mpc as mpc
            mpc.ferme_ton_clapet()


        # elif choix in ".":  # interrompt énoncé vocal en cours, on kille dans tous les cas, pas besoin de vérifier si un message est en cours de lecture
            # msg = "--> la touche . dans inp_loop a interrompu le message vocal"
            # infos.g_m(msg)
            # import inc.mpc as mpc
            # mpc.killer_pico()


        # menu commun
        elif choix in mnu_commun.keys():
            une_commandedescription mnu_commun.get(choix)
            if infos.ini_get("mode_apprentissage""off") == "on":
                msg la_les_touches(choix) + " " choix " " description
                infos.pdrNew(msg)
            else:
                commande(choixune_commandedescription)


        # menu module
        elif choix in menu_module.keys():
            une_commandedescription menu_module.get(choix)
            if infos.ini_get("mode_apprentissage""off") == "on":
                msg la_les_touches(choix) + " " choix " " description
                infos.pdrNew(msg)
            else:
                commande(choixune_commandedescription)
                # 11 : on a quitté un menu spécial avec zéro
                if choix == "11":   # menu spécial module
                    # ~ infos.m_g("on a quitté un menu spécial, appelé avec 11, avec zéro,")
                    # ~ infos.m_g("ou bien on a tapé 11 dans un module")
                    infos.m_g("choix = 11, on a quitté un menu vocal")
                    # dans les deux cas, on n'enregistyre pas de
                    # nouvelle valeur pour py_current_module

                elif infos.ini_get("py_current_module""juk") == "juk":
                    # c'est ici qu'on décide si on démarre/reprend un module
                    nouveauMod cfg.mnu_juk_activer.get(choix)

                    # bug ici quand on quitte le menu spécial 11 jukebox avec la touche 0
                    # nouveauMod prend la valeur None
                    # bug plantant évité grâce à la condition plus haut : if choix == "11":
                    infos.m_g(" ---> bug$$$, choix = {}".format(choix))
                    infos.m_g(" ---> bug$$$, nouveauMod = {}".format(nouveauMod))

                    infos.ini_set("py_current_module"nouveauMod)
                    infos.m_g("inp_loop, module " infos.ini_get("py_current_module""juk"))

        # ~ # 11 : on a quitté un menu spécial avec zéro
        # ~ elif choix in [ "11", ]:
            # ~ infos.m_g("on a quitté un menu spécial avec zéro")


        # mauvaise séquence (bipper ?)
        else:
            msg "Aucune action associée " a_la_les_touches(choix)
            infos.pdrNew(msg)


def start():
    """ accueil tout premier démarrage de jukebox.py """

    def willkommen():
        """ démarrage de l'application """
        # with open(cfg.fichierVersion) as fileVersion:
            # version_actu = fileVersion.readlines()[0].strip()

        infos.m_g("---------------------------------------------")
        infos.m_g("  Bienvenue dans " NOM_APPLI)
        infos.m_g("  version " mtn.version_current())
        infos.m_g("  màj     " mtn.version_update())
        infos.m_g("---------------------------------------------")
        msg1 "Bienvenue dans " NOM_APPLI
        if infos.niveau_aide_voc() == 0:
            dire_aide_vocale ""
        else:
            dire_aide_vocale ", aide vocale " str(infos.niveau_aide_voc())

        aujourdhui commun.date_heure_fr()
        # mnu_aide_voc = "pressez la séquences de touches " + \
            # "33 pour basculer l'aide vocale, " + \
            # "11 pour lancer le menu vocal"
        mnu_aide_voc "pressez la séquences de touches " \
            "00 si vous êtes perdu"
        msg1 += dire_aide_vocale ", " aujourdhui ", " mnu_aide_voc
        msg2 msg1
        infos.pdrNew([msg1msg2])

    def clean_crash():
        """ nettoie les fichiers en attente
            qui seraient restés après un crash ou une extinction sauvage
        """
        # supprimer éventuel flags arrêt thread
        mpc.sub_proc("rm /m/quitter_download")
        mpc.sub_proc("rm /m/quitter_dire")

        # au démarrage de l'appli :
        # supprimer tous les livres en attente de download
        mpc.sub_proc("rm /m/aba_dl_bg_*.txt")
        mpc.sub_proc("rm -rf /m/temp_dl_media")
        mpc.sub_proc("rm -rf /m/tmp_undef")
        # mettre à jour toute la base mpd
        mpc.update()

    def ligne_commande():
        """ automatisation des commandes """
        # Commandes batch depuis la ligne de commande, cf. doc01
        import sys
        if len(sys.argv) > 1:
            les_argus sys.argv[1:]
            infos.m_g(str(len(les_argus)) + " arguments fournis : ")
            0
            for in les_argus:
                += 1
                infos.m_g("- argument {} : {}".format(ni))
            automate_jk(les_argus)

    # TODO : tester si file system en lecture seule
    # symptôme : message prononcé se répète à l'infini
    # dans ce cas, rebooter
    stats_dev()
    mpc.clear()
    cmd "[ -d {0} ] || mkdir {0}".format(cfg.DIRE_FILE_ATTENTE)
    make_dir_plz mpc.sub_proc(cmd)
    clean_crash()
    infos.ini_set("py_current_module""juk")
    infos.ini_set("mode_apprentissage""off")
    willkommen()
    ligne_commande()
    inp_loop()


def stats_dev():
    """ nb de lignes par module,
        nb fonctions par module
    """

    def dossier_fichiers(dossierlist_fichiers):
        nb_lignesnb_fonctions 00
        infos.m_g("Dossier {}".format(dossier))
        for in list_fichiers:
            nb_lignes_fnb_fonctions_f stat_py(dossieri)
            nb_lignes += nb_lignes_f
            nb_fonctions += nb_fonctions_f
        infos.m_g("Total               {:>5d} lignes, {:>4d} fonctions".format(nb_lignesnb_fonctions))
        return int(nb_lignes), int(nb_fonctions)

    def stat_py(pathnom):
        cmd "wc -l < {}/{}.py".format(pathnom)
        nb_lignes mpc.sub_proc(cmd)
        cmd "grep '^def ' < {}/{}.py | wc -l".format(pathnom)
        nb_fonctions mpc.sub_proc(cmd)
        cmd "grep '^def ' < {}/{}.py".format(pathnom)
        fonctions mpc.sub_proc(cmd)
        infos.m_g("{:>8s}.py, {:>4s} lignes, {:>4s} fonctions".format(nomnb_lignesnb_fonctions))
        return int(nb_lignes), int(nb_fonctions)

    l1f1 dossier_fichiers("/opt/jk2019/tou_py", ["cfg""jukebox"])
    infos.m_g("")

    l3f3 dossier_fichiers("/opt/jk2019/tou_py/inc", ["infos""inputkiz""mpc"])
    infos.m_g("")

    l2f2 dossier_fichiers("/opt/jk2019/tou_py/mod", ["aba""commun""mtn""rad""zik"])
    total_L l1 l2 l3
    total_F f1 f2 f3
    infos.m_g("")
    infos.m_g("Total global : {} lignes, {} fonctions".format(total_Ltotal_F))


def plantage():
    """ enreguistrer lke journal de plantage
        et l'envoyer par mail ou web
    """
    print("except " "." 100)
    infos.m_g("Le programme a planté")
    infos.m_g("Le programme a planté")

    # prononcer en natif ici, pas d'arrière-plan
    texte "Le programme a planté."
    wav cfg.WAV_WAV
    cmd 'pico2wave -l "fr-FR" -w ' wav ' "' texte '"'
    mpc.sub_proc(cmd)
    # jouer wav
    cmd "aplay -q " wav
    infos.m_g(cmd)
    mpc.sub_proc(cmd)

    from time import localtimestrftime
    date_plantage strftime("%Y-%m-%d %H:%M:%S"localtime())
    date_fichier strftime("%Y%m%d_%H%M%S"localtime())

    fich_log "/m/plantage_" str(date_fichier) + ".txt"
    fplant open(fich_log"a")
    fplant.write("Date plantage : " str(date_plantage "\n"))
    traceback.print_exc(file=fplant)
    fplant.write("\n")
    fplant.write("Fin  plantage : " str(date_plantage "\n"))
    fplant.close()
    infos.m_g("Fichier " fich_log " appendé")

    cmd "curl -F \"avatar=@" fich_log "\" http://gangand.net/gl/kinote/upload.php"
    infos.m_g(cmd)
    mpc.sub_proc(cmd)

    cmd "touch /m/quitter_download"
    infos.m_g(cmd)
    mpc.sub_proc(cmd)

    cmd "touch /m/quitter_dire"
    infos.m_g(cmd)
    mpc.sub_proc(cmd)

    # thread téléchargements
    cmd "rm /m/aba_dl_bg_*.txt"
    infos.m_g(cmd)
    mpc.sub_proc(cmd)

    # utile ?
    cmd "rm -rf /m/temp_dl_media"
    infos.m_g(cmd)
    mpc.sub_proc(cmd)

    # thread pronciation
    cmd "rm -rf {}".format(cfg.DIRE_FILE_ATTENTE)
    infos.m_g(cmd)
    mpc.sub_proc(cmd)


import traceback
if __name__ == "__main__":
    start()
    # ~ try:
        # ~ start()
    # ~ except Exception as inst:
        # ~ print("excep " + "." * 100)
        # ~ print("Exception dans le module de départ jukebox.py")
        # ~ print("tout nettoyer et relancer le programme")
        # ~ print(type(inst))    # the exception instance
        # ~ print(inst.args)     # arguments stored in .args
        # ~ print(inst)          # __str__ allows args to be printed directly,
                             # ~ # but may be overridden in exception subclasses
        # ~ plantage()
        # ~ commun.faire_pause(5)
        # ~ import sys
        # ~ sys.exit()