# -*- coding: UTF-8 -*-
from py.test import raises
from glob import glob
from os.path import isdir, isfile, islink, lexists, exists
from os import system, listdir
from creole.client import CreoleClient
from time import sleep
import ftplib, imaplib

from pyeole.process import system_code, system_out
from fichier import quota
from scribe.eolegroup import Group
from scribe.eleves import Eleve
from scribe.enseignants import Enseignant
from scribe.eoleshare import Share
from scribe.eolead import member_test
from scribe.errors import NotEmptyGroup

dico = CreoleClient().get_creole()

smb = dico['container_ip_fichier']
imap = dico['container_ip_mail']
if 'smb_netbios_name' in dico:
    realm = dico['ad_domain']
    netbios_name = dico['smb_netbios_name']
    profilattr = 'sambaProfilePath'
else:
    realm = dico['ad_realm']
    netbios_name = dico['ad_server_netbios_name_member']
    profilattr = 'profilePath'
sympa_path = '%s/var/lib/sympa/expl/i-*/tclasse' % dico['container_path_mail']
mount_cmd = 'mount -t cifs'
mount_opts = ',vers=3.0,_netdev,domain={}'.format(realm)
password = 'Eole12345!'

# droits attendus pour le répertoire créé via FTP
ftpacl = """# file: home/t/televe/perso/testmkdirftp/
# owner: televe
# group: domain\\040users
user::rwx
user:televe:rwx
group::---
group:professeurs:r-x
mask::rwx
other::---
default:user::rwx
default:user:televe:rwx
default:group::---
default:group:professeurs:r-x
default:mask::rwx
default:other::---

"""

def test_create_niveau():
    Group().add_niveau('tnivo')

def test_create_classe():
    grp = Group()
    grp.add_classe('tclasse', 'tnivo')
    assert isdir('/home/workgroups/tclasse/donnees')
    assert isdir('/home/workgroups/profs-tclasse')
    assert 'tnivo' == grp.get_niveau('tclasse')
    assert glob(sympa_path) != []

def test_create_groupe():
    Group().add_groupe('tgroupe', partage='dt')
    assert isdir('/home/workgroups/tgroupe/travail')

def test_create_eleve():
    Eleve().add_one(login='televe', password=password, nom='nom',
                    prenom='prenom', date='01021980', classe= 'tclasse',
                    numero='666', civilite='1', domaine='restreint',
                    quota='20', profil='3', shell=False, entlogin=False)
    assert isdir('/home/t/televe/perso/prive')
    idx = 0
    maildir = '/home/mail/televe'
    while True:
        sleep(0.5)
        try:
            assert set(listdir(maildir)) == set(['cur', 'new', 'tmp'])
        except FileNotFoundError as err:
            idx += 1
            if idx == 10:
                raise err from err
        else:
            break
    # liens classe -> eleves
    assert isdir('/home/workgroups/profs-tclasse/eleves/televe')

def test_create_prof():
    Enseignant().add_one(login='tprof', password=password, nom='nom',
                         prenom='prenom', date='01021980', civilite='1',
                         classe='tclasse', entlogin=False)
    assert isdir('/home/t/tprof/perso')
    idx = 0
    maildir = '/home/mail/tprof'
    while True:
        sleep(0.5)
        try:
            assert set(listdir(maildir)) == set(['cur', 'new', 'tmp'])
        except FileNotFoundError as err:
            idx += 1
            if idx == 10:
                raise err from err
        else:
            break

def test_inscription_prof():
    ens = Enseignant()
    ens.ldap_admin.connect()
    ens._inscription('tprof', 'profs-tclasse')
    ens.ldap_admin.close()
    assert isdir('/home/t/tprof/.ftp/profs-tclasse')
    assert isdir('/home/t/tprof/groupes/profs-tclasse')

def test_inscription_eleve():
    ele = Eleve()
    ele.ldap_admin.connect()
    ele._inscription('televe', 'tgroupe')
    ele.ldap_admin.close()
    assert isdir('/home/t/televe/.ftp/tgroupe')
    assert isdir('/home/t/televe/groupes/tgroupe')

def test_force_lsc():
    if isfile('/usr/share/eole/schedule/scripts/eolead'):
        assert system('/usr/share/eole/schedule/scripts/eolead') == 0

def test_smb_perso_eleve():
    system('mkdir -p /tmp/home')
    assert system('%s //%s/televe /tmp/home -o username=televe,password=%s%s' % (mount_cmd, smb, password, mount_opts)) == 0
    system('touch /tmp/home/perso/fichier.txt')
    assert isfile('/tmp/home/perso/fichier.txt')
    system('rm -f /tmp/home/perso/fichier.txt')
    assert not isfile('/tmp/home/perso/fichier.txt')
    # test antivirus temps réel
    if dico.get('smb_vscan', 'non') == 'oui':
        system("""echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > /tmp/home/perso/virus.txt""")
        sleep(2)
        assert not isfile('/tmp/home/perso/virus.txt')
        system('rm -f /tmp/home/perso/virus.txt')

def test_smb_classe_eleve():
    system('mkdir -p /tmp/classe')
    assert system('%s //%s/tclasse /tmp/classe -o username=televe,password=%s%s' % (mount_cmd, smb, password, mount_opts)) == 0
    system('touch /tmp/classe/travail/fichier.txt')
    assert isfile('/tmp/classe/travail/fichier.txt')
    system('rm -f /tmp/classe/travail/fichier.txt')
    assert not isfile('/tmp/classe/travail/fichier.txt')
    system('touch /tmp/classe/donnees/fichier.txt')
    assert not isfile('/tmp/classe/donnees/fichier.txt')
    system('rm -f /tmp/classe/donnees/fichier.txt')

def test_smb_equipe_prof():
    system('mkdir -p /tmp/equipe')
    assert system('%s //%s/profs-tclasse /tmp/equipe -o username=tprof,password=%s%s' % (mount_cmd, smb, password, mount_opts)) == 0
    assert isdir('/tmp/equipe/eleves/televe')
    if dico.get('smb_unixextensions', 'no') != 'yes':
        # pas le droit de scanner le privé (FIXME : problème avec unixextensions)
        print("FIXME : listdir #1025")
        raises(OSError, listdir, '/tmp/equipe/eleves/televe/prive')

def test_demontage():
    # on regroupe tous les démontages
    system('umount /tmp/home/')
    system('umount /tmp/classe')
    system('umount /tmp/equipe')

def test_ftp_eleve():
    if dico['activer_proftpd'] == 'oui':
        system('rm -rf /home/t/televe/perso/testmkdirftp/')
        session = ftplib.FTP(smb, 'televe', password)
        session.cwd("perso")
        session.mkd("testmkdirftp")
        session.quit()
        assert system_out(['getfacl', '/home/t/televe/perso/testmkdirftp/'])[1] == ftpacl

def test_mail_eleve():
    mail = imaplib.IMAP4(imap)
    mail.login('televe', password)
    mail.select('inbox')
    assert b'Subject:' in mail.fetch('1', "(body[header])")[1][0][1]
    mail.close()
    mail.logout()

def test_mail_prof():
    mail = imaplib.IMAP4(imap)
    mail.login('tprof', password)
    mail.select('inbox')
    assert b'Subject:' in mail.fetch('1', "(body[header])")[1][0][1]
    mail.close()
    mail.logout()

def test_mod_mail():
    ens = Enseignant()
    ens.ldap_admin.connect()
    ens._mod_mail('tprof', mailtype='perso', mail='tprof@tprof.com')
    assert ens._get_attr('tprof', 'mail') == ['tprof@tprof.com']
    assert ens._get_attr('tprof', 'mailDir') == []
    assert ens._get_attr('tprof', 'mailHost') == []
    ens.ldap_admin.close()

def test_profils():
    ele = Eleve()
    ens = Enseignant()
    ele.ldap_admin.connect()
    ens.ldap_admin.connect()
    # profils à la création
    assert ele._get_attr('televe', profilattr) == ["\\\\{}\\netlogon\\profil2".format(netbios_name)]
    assert ele._get_attr('tprof', profilattr) == []
    # modification de profils
    ens._set_profil('tprof', 2)
    assert ens._get_attr('tprof', profilattr) == ["\\\\{}\\netlogon\\profil".format(netbios_name)]
    ens._set_profil('tprof', 4)
    assert ens._get_attr('tprof', profilattr) == ["\\\\{}\\tprof\\profil".format(netbios_name)]
    ens._set_profil('tprof', 1)
    assert ens._get_attr('tprof', profilattr) == []
    ele.ldap_admin.close()
    ens.ldap_admin.close()

def test_quotas():
    # quotas à la création
    assert quota.get_quota('televe') == 20
    assert quota.get_quota('tprof') == 0
    # modification de quotas
    quota.set_quota('tprof', 50)
    assert quota.get_quota('tprof') == 50

def test_delete_not_empty_classe():
    raises(NotEmptyGroup, Group().delete, 'tclasse')

def test_desinscription():
    ele = Eleve()
    ele.ldap_admin.connect()
    ele._desinscription('televe', 'tgroupe')
    assert not isdir('/home/t/televe/.ftp/tgroupe')
    assert not isdir('/home/t/televe/groupes/tgroupe')
    ele.ldap_admin.close()

def test_delete_eleve():
    Eleve().delete('televe', remove_data=True)
    assert not isdir('/home/t/televe')
    assert not islink('/home/tclasse/televe')

def test_delete_prof():
    Enseignant().delete('tprof', remove_data=True)
    assert not isdir('/home/t/tprof')

def test_delete_shares():
    sha = Share()
    sha.ldap_admin.connect()
    sha._delete('tclasse', rmdir=True, sync=False)
    assert not isdir('/home/workgroups/tclasse')
    sha._delete('profs-tclasse', rmdir=True, sync=False)
    assert not isdir('/home/workgroups/profs-tclasse')
    sha._delete('tgroupe', rmdir=True, sync=False)
    assert not isdir('/home/workgroups/tgroupe')
    sha.ldap_admin.close()

def test_delete_classe():
    grp = Group()
    grp.delete('tclasse', rmdir=True, sync=False)
    assert not isdir('/home/workgroups/profs-tclasse')
    assert not isdir('/home/classes/tclasse')
    assert glob(sympa_path) == []

def test_delete_groups():
    grp = Group()
    grp.delete('tnivo', rmdir=True, sync=False)
    grp.delete('tgroupe', rmdir=True, sync=False)

