# --- BEGIN COPYRIGHT BLOCK ---
# Copyright (C) 2020 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
#
import time
import pytest
import logging
import os

from lib389 import DEFAULT_SUFFIX
from lib389.cli_idm.client_config import sssd_conf, ldap_conf, display
from lib389.plugins import MemberOfPlugin
from lib389.topologies import topology_st
from lib389.cli_base import FakeArgs
from lib389.idm.group import Groups
from lib389.idm.user import nsUserAccounts
from lib389.utils import ds_is_older

pytestmark = pytest.mark.tier0

LOG_FILE = '/tmp/dsidm.log'
logging.getLogger(__name__).setLevel(logging.DEBUG)
log = logging.getLogger(__name__)


@pytest.fixture(scope="function")
def set_log_file(request):
    fh = logging.FileHandler(LOG_FILE)
    fh.setLevel(logging.DEBUG)
    log.addHandler(fh)

    def fin():
        log.info('Delete log file')
        os.remove(LOG_FILE)

    request.addfinalizer(fin)


def check_value_in_log_and_reset(content_list, content_list2=None, check_value=None):
    with open(LOG_FILE, 'r+') as f:
        file_content = f.read()
        if content_list2 is not None:
            log.info('Check if content is present in output')
            for item in content_list + content_list2:
                assert item.lower() in file_content.lower()
        else:
            log.info('Check if content is present in output')
            for item in content_list:
                assert item.lower() in file_content.lower()

        if check_value is not None:
            log.info('Check if value is present in output')
            assert check_value in file_content

        log.info('Reset log file for next test')
        f.truncate(0)


@pytest.mark.skipif(ds_is_older("1.4.2"), reason="Not implemented")
def test_dsidm_config_sssd(topology_st, set_log_file):
    """ Test dsidm creation of sssd.conf content

    :id: 77812ba6-b133-40f4-91a7-13309618f24d
    :setup: Standalone instance
    :steps:
         1. Run dsidm client_config sssd.conf
         2. Enable MemberOfPlugin
         3. Run dsidm client_config sssd.conf with allowed group
    :expectedresults:
         1. Success
         2. Success
         3. Success
    """

    standalone = topology_st.standalone

    sssd_content_list = ['Generated by 389 Directory Server - dsidm',
                         'id_provider = ldap',
                         'auth_provider = ldap',
                         'access_provider = ldap',
                         'chpass_provider = ldap',
                         'ldap_search_base = ' + DEFAULT_SUFFIX,
                         'ldap_uri = ' + standalone.ldapuri,
                         'ldap_user_member_of = memberof',
                         'ignore_group_members = False',
                         '[sssd]',
                         'services = nss, pam, ssh, sudo',
                         'config_file_version = 2',
                         'domains = ldap',
                         '[nss]',
                         'homedir_substring = /home']

    schema = 'ldap_schema = rfc2307'
    args = FakeArgs()
    args.allowed_group = None

    log.info('Create sssd.conf content')
    sssd_conf(standalone, DEFAULT_SUFFIX, log, args)

    log.info('Check if config creation was successful')
    check_value_in_log_and_reset(sssd_content_list, check_value=schema)

    log.info('Now we test allowed_group argument')
    log.info('Enable MemberOf plugin')
    plugin = MemberOfPlugin(standalone)
    plugin.enable()
    standalone.restart()

    log.info('Create test group')
    groups = Groups(standalone, DEFAULT_SUFFIX)
    test_group = groups.create(properties={"cn": "new_group",
                                           "description": "testgroup"})

    log.info('Create sssd.conf content with allowed group')
    filter_msg = ['ldap_access_filter = (memberOf={})'.format(test_group.dn), 'ldap_schema = rfc2307bis']
    args.allowed_group = test_group.rdn
    sssd_conf(standalone, DEFAULT_SUFFIX, log, args)

    log.info('Check if config creation was successful')
    check_value_in_log_and_reset(sssd_content_list, filter_msg)


@pytest.mark.skipif(ds_is_older("1.4.2"), reason="Not implemented")
def test_dsidm_config_ldap(topology_st, set_log_file):
    """ Test dsidm creation of ldap.conf content

    :id: 29ffcc91-9104-4c90-bcdf-0f6a4082322c
    :setup: Standalone instance
    :steps:
         1. Create instance
         2. Run dsidm client_config ldap.conf
    :expectedresults:
         1. Success
         2. Success
    """

    standalone = topology_st.standalone
    args = FakeArgs()

    ldap_content_list = ['OpenLDAP client configuration',
                         'Generated by 389 Directory Server - dsidm',
                         'BASE    ' + DEFAULT_SUFFIX,
                         'URI     ' + standalone.ldapuri,
                         'DEREF   never',
                         'TLS_CACERTDIR /etc/openldap/certs']

    log.info('Create ldap.conf content')
    ldap_conf(standalone, DEFAULT_SUFFIX, log, args)

    log.info('Check if config creation was successful')
    check_value_in_log_and_reset(ldap_content_list)


@pytest.mark.skipif(ds_is_older("1.4.2"), reason="Not implemented")
def test_dsidm_config_display(topology_st, set_log_file):
    """ Test dsidm display option

    :id: 6e888ae2-8835-44d5-846b-e971d76aa461
    :setup: Standalone instance
    :steps:
         1. Run dsidm client_config display
         2. Enable MemberOfPlugin
         3. Run dsidm client_config display with MemberOfPlugin
    :expectedresults:
         1. Success
         2. Success
         3. Success
    """

    standalone = topology_st.standalone
    users = nsUserAccounts(standalone, DEFAULT_SUFFIX)
    groups = Groups(standalone, DEFAULT_SUFFIX)

    display_content_list = ['ldap_uri = ' + standalone.ldapuri,
                            'ldap_uri = ldaps:///dc%3Dexample%2Cdc%3Dcom',
                            'group_basedn = ' + groups._basedn,
                            'basedn = ' + DEFAULT_SUFFIX,
                            'user_basedn = ' + users._basedn,
                            'user_filter = (&(objectclass=nsPerson)(objectclass=nsAccount)(objectclass=nsOrgPerson)'
                            '(objectclass=posixAccount))',
                            'unique id = nsUniqueId',
                            'group member attribute = member',
                            'user rdn = uid',
                            'user identifier = uid',
                            'group_filter = (&(objectclass=groupOfNames))',
                            'group rdn = cn']

    schema_type = 'rfc2307'
    args = FakeArgs()

    log.info('Test dsidm display option')
    display(standalone, DEFAULT_SUFFIX, log, args)

    log.info('Check if display option was successful')
    check_value_in_log_and_reset(display_content_list, check_value=schema_type)

    log.info('Enable MemberOf plugin')
    plugin = MemberOfPlugin(standalone)
    plugin.enable()
    standalone.restart()

    log.info('Test dsidm display option with MemberOf plugin')
    display(standalone, DEFAULT_SUFFIX, log, args)

    log.info('Check if display option was successful with MemberOf plugin enabled')
    schema_type = 'rfc2307bis'
    check_value_in_log_and_reset(display_content_list, check_value=schema_type)


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