import ldap
from ldap.modlist import addModlist, modifyModlist
from config import V5Config

def get_member(username):
    """ Get informations about member. Username must be normalized! """
    conn = ldap.initialize("ldap://localhost")
    # Search for user
    r = conn.search_s(V5Config.LDAP_ORGANIZATION, ldap.SCOPE_SUBTREE,
        f'(cn={username})')
    if len(r) > 0:
        return r[0]
    else:
        return None


def edit(user, fields):
    """ Edit a user. Fields is {'name': ['value'], …} """
    conn = ldap.initialize("ldap://localhost")
    # Connect as root
    # conn.simple_bind_s(f'cn=ldap-root,{LDAP_ORGANIZATION}', LDAP_PASSWORD)
    # old_value = {"userPassword": ["my_old_password"]}
    # new_value = {"userPassword": ["my_new_password"]}

    modlist = ldap.modlist.modifyModlist(old_value, new_value)
    con.modify_s(dn, modlist)


def set_email(user, email):
    pass


def set_password(user, password):
    """ Set password for a user. """
    conn = ldap.initialize("ldap://localhost")
    # Connect as root
    conn.simple_bind_s(f'cn=ldap-root,{V5Config.LDAP_ORGANIZATION}',
        V5Config.LDAP_PASSWORD)
    conn.passwd_s(f"cn={user.norm},{V5Config.LDAP_ORGANIZATION}",
        None, password)


def check_password(user, password):
    """ Try to login a user through LDAP register. """
    conn = ldap.initialize("ldap://localhost")
    try:
        conn.simple_bind_s(f"cn={user.norm},{V5Config.LDAP_ORGANIZATION}",
            password)
    except ldap.INVALID_CREDENTIALS:
        return False
    return True


def add_member(member):
    """ Add a member to LDAP register. Fields must have been sanitized! """
    if get_member(member.norm) is not None:
        print("User already exists")
        return
    conn = ldap.initialize("ldap://localhost")
    # Connect as root
    conn.simple_bind_s(f'cn=ldap-root,{V5Config.LDAP_ORGANIZATION}',
        V5Config.LDAP_PASSWORD)
    # Create fields
    dn = f'cn={member.norm},{V5Config.LDAP_ORGANIZATION}'
    modlist = addModlist({
        'objectClass': [bytes('inetOrgPerson', 'UTF8')],
        'cn': [bytes(member.norm, 'UTF8')],
        'sn': [bytes(member.norm, 'UTF8')],
        'displayName': [bytes(member.name, 'UTF8')],
        'mail': [bytes(member.email, 'UTF8')],
        'uid': [bytes(str(member.id), 'UTF8')],
        'userPassword': [bytes("", 'UTF8')]
    })
    # Add the member
    conn.add_s(dn, modlist)


def delete_member(member):
    """ Remove a member from LDAP register """
    conn = ldap.initialize("ldap://localhost")
    # Connect as root
    conn.simple_bind_s(f'cn=ldap-root,{V5Config.LDAP_ORGANIZATION}',
        V5Config.LDAP_PASSWORD)
    # Create fields
    dn = f'cn={member.norm},{V5Config.LDAP_ORGANIZATION}'
    # Delete the user
    conn.delete_s(dn)
