import logging
import pytest
import os
import ldap
import re
import base64
from lib389 import Entry
from lib389._constants import *
from lib389.topologies import topology_m2 as topo

DEBUGGING = os.getenv("DEBUGGING", default=False)
if DEBUGGING:
    logging.getLogger(__name__).setLevel(logging.DEBUG)
else:
    logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)

PASSWORD_ADD = "password_during_add"
PASSWORD_MOD = "password_during_mod"
def add_user(server, uid, testbase):
    dn = 'uid=%s,%s' % (uid, testbase)
    log.fatal('Adding user (%s): ' % dn)
    server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson'],
                             'cn': 'user_%s' % uid,
                             'sn': 'user_%s' % uid,
                             'uid': uid,
                             'userpassword': PASSWORD_ADD})))
    return dn

def test_ticket50070(topo):
    """Specify a test case purpose or name here

    :id: 7adc995b-85f9-4398-ba0a-c766b5b13bbe
    :setup: 2 Master Instances
    :steps:
        1. Fill in test case steps here
        2. And indent them like this (RST format requirement)
    :expectedresults:
        1. Fill in the result that is expected
        2. For each test step
    """

    M1 = topo.ms["master1"]
    M2 = topo.ms["master2"]
    
    M1.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
    M1.restart()
    
    M2.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
    M2.restart()

    # Create a user and log the value of its password
    testbase = "ou=people,%s" % SUFFIX
    testuser = add_user(M1, 'testuser', testbase)
    ents = M1.search_s("cn=changelog", ldap.SCOPE_SUBTREE,"(&(targetDN=%s)(changeType=add))" % testuser,["changes"])
    assert len(ents) == 1
    assert ents[0].hasAttr("changes")
    value = ents[0].getValue("changes")
    assert value
    password_started = False
    userpassword =b''
    for line in value.split(b'\n'):
        log.debug("ADD line: %s" % line)
        if line.lower().startswith(b'userpassword'):
            # This is the beginning of the userpassword
            
            x = line[len('userpassword:'):]
            if x.startswith(b':'):
                x = x[1:]
            x = x[1:]
            log.debug("x: %s" % x)
            password_started = True
            userpassword = userpassword + x
        elif password_started:
            if line.startswith(b' '):
                # this is the continuation of userpassword
                x = line[1:]
                log.debug("x: %s" % x)
                userpassword = userpassword + x
            #else:
                # this is a new attribute
                #break
    log.debug("resultat ====> %s" % base64.b64decode(userpassword))
    
    CLEAR_TXT_PASSWORD = b'modifiedpassword'
    M1.modify_s(testuser, [(ldap.MOD_REPLACE, 'userpassword', CLEAR_TXT_PASSWORD)])
    ents = M1.search_s("cn=changelog", ldap.SCOPE_SUBTREE,"(&(targetDN=%s)(changeType=modify))" % testuser,["changes"])
    assert ents[0].hasAttr("changes")
    value = ents[0].getValue("changes")
    assert value
    for line in value.split(b'\n'):
        log.debug("MOD line: %s" % line)
        if line.lower().startswith(b'unhashed#user#password'):
            # should not contain clear test password
            # and anyway should not contain unhashed#user#password in the retroCL
            assert CLEAR_TXT_PASSWORD not in line
            assert False 


    # If you need any test suite initialization,
    # please, write additional fixture for that (including finalizer).
    # Topology for suites are predefined in lib389/topologies.py.

    # If you need host, port or any other data about instance,
    # Please, use the instance object attributes for that (for example, topo.ms["master1"].serverid)

    if DEBUGGING:
        # Add debugging steps(if any)...
        pass


if __name__ == '__main__':
    # Run isolated
    # -s for DEBUG mode
    CURRENT_FILE = os.path.realpath(__file__)
    pytest.main(["-s", CURRENT_FILE])

