import pytest
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_st

DEBUGGING = os.getenv('DEBUGGING', False)
SUBTREE_1 ='cn=sub1,%s' % SUFFIX
SUBTREE_2 ='cn=sub2,%s' % SUFFIX

if DEBUGGING:
    logging.getLogger(__name__).setLevel(logging.DEBUG)
else:
    logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)

def config_memberof(server):

    server.plugins.enable(name=PLUGIN_MEMBER_OF)
    # set memberofentryscope
    dn = "cn=%s,%s" % (PLUGIN_MEMBER_OF, DN_PLUGIN)
    server.modify_s(dn, [(ldap.MOD_REPLACE, 'memberOfEntryScope', SUBTREE_1)])
    server.restart(timeout=10)

def add_container(server, dn):
    server.add_s(Entry((dn, {'objectclass': ['top', 'nscontainer']})))

def add_member(server, cn, subtree):
    dn = '%s,%s' % (cn, subtree)
    server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'inetuser'],
                             'sn': 'SN',
                             'description': 'member'})))

def add_group(server, cn, subtree):

    dn = '%s,%s' % (cn, subtree)
    server.add_s(Entry((dn, {'objectclass': ['top', 'groupofnames'],
                             'member': [
                                   'cn=m1,%s' % SUBTREE_1,
                                   'cn=m2,%s' % SUBTREE_1
                                   ],
                             'description': 'group'})))

def rename_entry(server, cn, from_subtree, to_subtree):
    dn = '%s,%s' % (cn, from_subtree)
    nrdn = '%s-new' % cn
    log.fatal('Renaming user (%s): new %s' % (dn, nrdn))
    server.rename_s(dn, nrdn, newsuperior=to_subtree, delold=0)

def _find_memberof(server, user_dn=None, group_dn=None, find_result=True):
    assert (server)
    assert (user_dn)
    assert (group_dn)
    ent = server.getEntry(user_dn, ldap.SCOPE_BASE, "(objectclass=*)", ['memberof'])
    found = False
    if ent.hasAttr('memberof'):

        for val in ent.getValues('memberof'):
            server.log.info("!!!!!!! %s: memberof->%s" % (user_dn, val))
            if val == group_dn:
                found = True
                break

    if find_result:
        assert (found)
    else:
        assert (not found)


def _enable_spec_logging(server):
    mods = [(ldap.MOD_REPLACE, 'nsslapd-accesslog-level', str(260)),  # Internal op
            (ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '65536'),
            (ldap.MOD_REPLACE, 'nsslapd-plugin-logging', 'on')]
    server.modify_s(DN_CONFIG, mods)


def test_ticket_49161(topology_st):
    """
        test case for memberof and move group

    """


    config_memberof(topology_st.standalone)

    add_container(topology_st.standalone, SUBTREE_1)
    add_container(topology_st.standalone, SUBTREE_2)
    add_member(topology_st.standalone, 'cn=m1', SUBTREE_1)
    add_member(topology_st.standalone, 'cn=m2', SUBTREE_1)
    add_group(topology_st.standalone,'cn=g1',SUBTREE_1)
    add_group(topology_st.standalone,'cn=g2',SUBTREE_2)

    # _check_memberof
    dn1 = '%s,%s' % ('cn=m1', SUBTREE_1)
    dn2 = '%s,%s' % ('cn=m1', SUBTREE_1)
    g1 = '%s,%s' % ('cn=g1', SUBTREE_1)
    g2 = '%s,%s' % ('cn=g2', SUBTREE_2)
    _find_memberof(topology_st.standalone, dn1, g1, True)
    _find_memberof(topology_st.standalone, dn2, g1, True)
    _find_memberof(topology_st.standalone, dn1, g2, False)
    _find_memberof(topology_st.standalone, dn2, g2, False)

    rename_entry(topology_st.standalone,'cn=g2',SUBTREE_2,SUBTREE_1)

    g2n = '%s,%s' % ('cn=g2-new', SUBTREE_1)
    _find_memberof(topology_st.standalone, dn1, g1, True)
    _find_memberof(topology_st.standalone, dn2, g1, True)
    _find_memberof(topology_st.standalone, dn1, g2n, True)
    _find_memberof(topology_st.standalone, dn2, g2n, True)


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