# --- BEGIN COPYRIGHT BLOCK ---
# Copyright (C) 2017 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
#
import pytest
from lib389.replica import Replicas
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_m2 as topo_m2
from . import get_repl_entries
from lib389.idm.user import UserAccount
from lib389.replica import ReplicationManager
from lib389._constants import *

pytestmark = pytest.mark.tier0

TEST_ENTRY_NAME = 'mmrepl_test'
TEST_ENTRY_DN = 'uid={},{}'.format(TEST_ENTRY_NAME, DEFAULT_SUFFIX)
NEW_SUFFIX_NAME = 'test_repl'
NEW_SUFFIX = 'o={}'.format(NEW_SUFFIX_NAME)
NEW_BACKEND = 'repl_base'

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

def test_rfc2307compat(topo_m2):
    """ Test to verify if 10rfc2307compat.ldif does not prevent replication of schema
        - Create 2 masters and a test entry
        - Move 10rfc2307compat.ldif to be private to M1
        - Move 10rfc2307.ldif to be private to M2
        - Add 'objectCategory' to the schema of M1
        - Force a replication session
        - Check 'objectCategory' on M1 and M2
    """
    m1 = topo_m2.ms["master1"]
    m2 = topo_m2.ms["master2"]

    m1.add_s(Entry((
        TEST_ENTRY_DN, {
            "objectClass": "top",
            "objectClass": "extensibleObject",
            'uid': TEST_ENTRY_NAME,
            'cn': TEST_ENTRY_NAME,
            'sn': TEST_ENTRY_NAME,
        }
    )))

    entries = get_repl_entries(topo_m2, TEST_ENTRY_NAME, ["uid"])
    assert all(entries), "Entry {} wasn't replicated successfully".format(TEST_ENTRY_DN)

    # Stop all instances
    m1.stop()
    m2.stop()
    
    # move 60posix-winsync-plugin.ldif to data because of dependency on posixGroup
    for file in ('60posix-winsync-plugin.ldif', '60samba3.ldif'):
        schema_filename = (m1.get_data_dir() + "/dirsrv/schema/%s" % file)
        data_filename = (m1.get_data_dir() + "/dirsrv/data/%s" % file)
        try:
            shutil.move(schema_filename, data_filename)
        except:
            pass

    # move 10rfc2307compat.ldif private M1
    schema_rfc2307compat_filename = (m1.get_data_dir() + "/dirsrv/schema/10rfc2307compat.ldif")
    m1_rfc2307compat_filename = (m1.schemadir + "/10rfc2307compat.ldif")
    shutil.move(schema_rfc2307compat_filename, m1_rfc2307compat_filename)

    # move 10rfc2307.ldif private M2
    schema_rfc2307_filename = (m2.get_data_dir() + "/dirsrv/data/10rfc2307.ldif")
    m1_rfc2307_filename = (m2.schemadir + "/10rfc2307.ldif")
    shutil.move(schema_rfc2307_filename, m1_rfc2307_filename)

    # udpate the schema on M1 to tag a schemacsn
    m1.start()
    objectcategory_attr = '( NAME \'objectCategory\' DESC \'test of objectCategory\' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )'
    m1.schema.add_schema('attributetypes', [ensure_bytes(objectcategory_attr)])

    # Now start M2 and trigger a replication M1->M2
    m2.start()
    m1.modify_s(TEST_ENTRY_DN, [(ldap.MOD_ADD, 'cn', [ensure_bytes('value_m1')])])

    # Now check that objectCategory is in both schema
    time.sleep(10)
    ents = m1.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes'])
    for value in ents[0].getValues('attributetypes'):
        if ensure_bytes('objectCategory') in value:
           log.info("M1: " + str(value))
           break
    assert ensure_bytes('objectCategory') in value
    
    ents = m2.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes'])
    for value in ents[0].getValues('attributetypes'):
        if ensure_bytes('objectCategory') in value:
           log.info("M2: " + str(value))
           break
    assert ensure_bytes('objectCategory') in value
    


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