from email_validator import validate_email, EmailNotValidError
from glob import glob
import tempfile
import subprocess
import re
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib

from .paheko import Paheko
from .ldap import Ldap
from .mattermost import Mattermost
from .sympa import Sympa
from .template import render_template
from .config import getDockersConfig, getSecretConfig

DEFAULT_FILE = "/kaz/tmp/createUser.txt"

webmail_url = f"https://webmail.{getDockersConfig('domain')}"
mattermost_url = f"https://agora.{getDockersConfig('domain')}"
mdp_url = f"https://mdp.{getDockersConfig('domain')}"
sympa_url = f"https://listes.{getDockersConfig('domain')}"
site_url = f"https://{getDockersConfig('domain')}"
cloud_url = f"https://cloud.{getDockersConfig('domain')}"


def _generate_password(self):
    cmd="apg -n 1 -m 10 -M NCL -d"
    output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
    new_password="_"+output.decode("utf-8")+"_"
    return new_password


def create_user(email, email_secours, admin_orga, nom_orga, quota_disque, nom, prenom, nc_orga, garradin_orga, wp_orga, agora_orga, wiki_orga, nc_base, groupe_nc_base, equipe_agora, password=None):
    email = email.lower()

    with Ldap() as ldap:
        # est-il déjà dans le ldap ? (mail ou alias)
        if ldap.get_email(email):
            print(f"ERREUR 1: {email} déjà existant dans ldap. on arrête tout")
            return None

        #test nom orga
        if admin_orga == 1:
          if nom_orga is None:
              print(f"ERREUR 0 sur paheko: {email} : nom_orga vide, on arrête tout")
              return
          if not bool(re.match(r'^[a-z0-9-]+$', nom_orga)):
              print(f"ERREUR 0 sur paheko: {email} : nom_orga ({tab['nom_orga']}) incohérent (minuscule/chiffre/-), on arrête tout")
              return

        #test email_secours
        email_secours = email_secours.lower()
        if not validate_email(email_secours):
            print("Mauvais email de secours")
            return

        #test quota
        quota = quota_disque
        if not quota.isdigit():
            print(f"ERREUR 2: quota non numérique : {quota}, on arrête tout")
            return

        #on génère un password
        password = password or _generate_password()

        #on créé dans le ldap
        #à quoi servent prenom/nom dans le ldap ?
        data = {
          "prenom": prenom,
          "nom": nom,
          "password": password,
          "email_secours": email_secours,
          "quota": quota
        }
        if not ldap.create_user(email, **data):
            print("Erreur LDAP")
            return

    with Mattermost() as mm:
        #on créé dans MM
        user = email.split('@')[0]
        mm.create_user(user, email, password)
        mm.add_user_to_team(email, "kaz")

        #et aux 2 canaux de base
        mm.add_user_to_channel(email, "kaz", "une-question--un-soucis")
        mm.add_user_to_channel(email, "kaz", "cafe-du-commerce--ouvert-2424h")

        #on créé une nouvelle équipe ds MM si besoin
        if admin_orga == 1:
          mm.create_team(nom_orga, email)
          #BUG: créer la nouvelle équipe n'a pas rendu l'email admin, on le rajoute comme membre simple
          mm.add_user_to_team(email, nom_orga)


    #on inscrit email et email_secours à la nl sympa_liste_info
    sympa = Sympa()
    sympa.add_email_to_list(email)
    sympa.add_email_to_list(email_secours)

    #on construit/envoie le mail
    context = {
        'ADMIN_ORGA': admin_orga,
        'NOM': f"{prenom} {nom}",
        'EMAIL_SOUHAITE': email,
        'PASSWORD': password,
        'QUOTA': quota_disque,
        'URL_WEBMAIL': webmail_url,
        'URL_AGORA': mattermost_url,
        'URL_MDP': mdp_url,
        'URL_LISTE': sympa_url,
        'URL_SITE': site_url,
        'URL_CLOUD': cloud_url,
    }

    html = render_template("email_inscription.html", context)
    raw = render_template("email_inscription.txt", context)

    message = MIMEMultipart()
    message["Subject"] = "KAZ: confirmation d'inscription !"
    message["From"] = f"contact@{getDockersConfig('domain')}"
    message["To"] = f"{email}, {email_secours}"
    message.attach(MIMEText(raw, "plain"))
    message.attach(MIMEText(html, "html"))

    with smtplib.SMTP(f"mail.{getDockersConfig('domain')}", 25) as server:
        server.sendmail(f"contact@{getDockersConfig('domain')}", [email,email_secours], message.as_string())

    #on met le flag paheko action à Aucune
    paheko = Paheko()
    try:
        paheko.set_user(email, "action_auto", "Aucune")
    except:
        print(f"Erreur paheko pour remettre action_auto = Aucune pour {email}")

    #on post sur MM pour dire ok
    with Mattermost() as mm:
        msg=f"**POST AUTO** Inscription réussie pour {email} avec le secours {email_secours} Bisou!"
        mm.post_message(message=msg)


def create_waiting_users():
    """
    Créé les kaznautes en attente: inscription sur MM / Cloud / email + msg sur MM + email à partir de action="a créer" sur paheko
    """
    #verrou pour empêcher de lancer en même temps la même api
    prefixe="create_user_lock_"
    if glob(f"{tempfile.gettempdir()}/{prefixe}*"):
        print("Lock présent")
        return None
    lock_file = tempfile.NamedTemporaryFile(prefix=prefixe,delete=True)

    #qui sont les kaznautes à créer ?
    paheko = Paheko()
    liste_kaznautes = paheko.get_users_with_action("A créer")

    if liste_kaznautes:
        count=liste_kaznautes['count']
        if count==0:
            print("aucun nouveau kaznaute à créer")
            return

        #au moins un kaznaute à créer
        for tab in liste_kaznautes['results']:
          create_user(**tab)

    print("fin des inscriptions")


def create_users_from_file(file=DEFAULT_FILE):
    """
    Créé les kaznautes en attente: inscription sur MM / Cloud / email + msg sur MM + email à partir du ficher
    """
    #verrou pour empêcher de lancer en même temps la même api
    prefixe="create_user_lock_"
    if glob(f"{tempfile.gettempdir()}/{prefixe}*"):
        print("Lock présent")
        return None
    lock_file = tempfile.NamedTemporaryFile(prefix=prefixe,delete=True)

    #qui sont les kaznautes à créer ?
    liste_kaznautes = []
    with open(file) as lines:
        for line in lines:
            line = line.strip()
            if not line.startswith("#") and line != "":
                user_data = line.split(';')
                user_dict = {
                    "nom": user_data[0],
                    "prenom": user_data[1],
                    "email": user_data[2],
                    "email_secours": user_data[3],
                    "nom_orga": user_data[4],
                    "admin_orga": user_data[5],
                    "nc_orga": user_data[6],
                    "garradin_orga": user_data[7],
                    "wp_orga": user_data[8],
                    "agora_orga": user_data[9],
                    "wiki_orga": user_data[10],
                    "nc_base": user_data[11],
                    "groupe_nc_base": user_data[12],
                    "equipe_agora": user_data[13],
                    "quota_disque": user_data[14],
                    "password": user_data.get(15),
                }
                liste_kaznautes.append(user_dict)

    if liste_kaznautes:
        for tab in liste_kaznautes:
          create_user(**tab)

    print("fin des inscriptions")