import logging
import pytest
import ldap
from lib389.idm.group import Groups
from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
from lib389.plugins import MemberOfPlugin, ReferentialIntegrityPlugin
import os
from lib389._constants import *
from lib389.topologies import topology_st as topo
from lib389.backend import Backends
from lib389.index import Indexes
from lib389.utils import ldap, os, logging, ensure_bytes

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__)


TEST_ENTRY_NAME = 'testuser'
TEST_GROUP_NAME = 'group1'


def _member_index_tune(topo, value):
    backends = Backends(topo)
    backend = backends.get(DEFAULT_BENAME)
    indexes = backend.get_indexes()

    for i in indexes.list():
        i_cn = i.get_attr_val_utf8('cn')
        if i_cn.lower() == 'member':
            i.replace('nsIndexType', value)
            

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

    :id: c4df8d93-91de-4189-9681-7a918e69649c
    :setup: Standalone Instance
    :steps:
        1. Create a test_user
        2. Create a test_group and make test_user member of test_group
        3. Disable memberof plugin, so that when test_user is deleted, test_group is not updated
        4. Break the 'member' index, making it ignore 'eq'
        5. remove test_user. test group is not updated and member: =<test_user>.dn --> test_group.entryId remains
        6. reenable 'eq' for member index
        7. Enable Referential integrity
        8. Enable filter logging (error log)
        9. delete test_user -> referint will search 'member=<test_user>.dn' and will Bypass the filter
    :expectedresults:
    """
    
    inst = topo.standalone
    inst.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'65536'),
                              (ldap.MOD_REPLACE, 'nsslapd-plugin-logging', b'on'),
                              (ldap.MOD_REPLACE, 'nsslapd-accesslog-level', b'260')])

    
    memberof = MemberOfPlugin(inst)
    memberof.enable()
    inst.restart()
    
    
    # Create a user
    log.info('Adding user {}'.format(TEST_ENTRY_NAME))
    users = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn=None)
    test_user = users.create(properties=TEST_USER_PROPERTIES)
    
    # Create weir user
    CN = b'weird user'
    user_props = TEST_USER_PROPERTIES.copy()
    user_props.update({'uid': CN, 'cn': CN, 'sn': '_%s' % CN, 'description': b'dummy value'})
    weird_user = users.create(properties=user_props)
    inst.modify_s(weird_user.dn, [(ldap.MOD_ADD, 'objectclass', b'referral')])
    
    DESC_VALUE = "NOT dummy value"
    ents = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(description=%s)' % DESC_VALUE)
    for ent in ents:
        log.info('Unexpected has no entry should match')
        if ent.hasAttr('description'):
            log.info('%s has description %s' % (ent.dn, ent.getValue('description')))
            assert ent.getValue('description') == DESC_VALUE
    assert len(ents) == 0
    
 
    
    # 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])

