import sys
import os
myPath = os.path.abspath(os.getcwd())
sys.path.insert(0, myPath)
import hubblestack.extmods.modules.pulsar as pulsar
from salt.exceptions import CommandExecutionError

import shutil
import six
import pyinotify

if os.environ.get('DEBUG_SHOW_PULSAR_LOGS'):
    import logging
    root_logger = logging.getLogger()
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    root_logger.addHandler(ch)

class TestPulsar():

    def test_virtual(self):
        var = pulsar.__virtual__()
        assert var is True

    def test_enqueue(self):
        pulsar.__context__ = {}
        var = pulsar._enqueue
        assert var != 0

    def test_get_notifier(self):
        pulsar.__context__ = {}
        var = pulsar._get_notifier
        assert var != 0

    def test_dict_update_for_merge_dict(self):
        dest = {'key1': 'val1'}
        upd = {'key_2': 'val_2'}
        test_dict = {'key1': 'val1', 'key_2': 'val_2'}
        var = pulsar._dict_update(dest, upd, recursive_update=True, merge_lists=False)
        assert var == test_dict

    def test_dict_update_for_classic_dictUpdate(self):
        dest = {'key1': 'val1'}
        upd = {'key_2': 'val_2'}
        test_dict = {'key1': 'val1', 'key_2': 'val_2'}
        var = pulsar._dict_update(dest, upd, recursive_update=False, merge_lists=False)
        assert var == test_dict

    def test_dict_update_for_dest_TypeError(self):
        dest = 'TestValue1'
        upd = {'key_1': 'val_1', 'key_2': 'val_2'}
        try:
            var = pulsar._dict_update(dest, upd, recursive_update=True, merge_lists=False)
        except TypeError:
            pass

    def test_dict_update_for_upd_TypeError(self):
        dest = {'key_1': 'val_1', 'key_2': 'val_2'}
        upd = 'TestValue2'
        try:
            var = pulsar._dict_update(dest, upd, recursive_update=True, merge_lists=False)
        except TypeError:
            pass

    def test_dict_update_recurssive(self):
        ret = {}
        dest = {'data':
                {'blacklist': {'talk1': {'data': {'Ubuntu-16.04': [{'/etc/inetd.conf': {'pattern': '^talk', 'tag': 'CIS-5.1.4'}}, {'/etc/inetd.conf': {'pattern': '^ntalk', 'tag': 'CIS-5.1.4'}}]}, 'description': 'Ensure talk server is not enabled'}},
                 'whitelist': {'ssh_ignore_rhosts': {'data': {'Ubuntu-16.04': [{'/etc/ssh/sshd_config': {'pattern': 'IgnoreRhosts', 'tag': 'CIS-9.3.6', 'match_output': 'yes'}}]}, 'description': 'Set SSH IgnoreRhosts to Yes'}}}}
        upd = {'data':
               {'blacklist': {'talk2': {'data': {'Ubuntu-16.04': [{'/etc/inetd.conf': {'pattern': '^talk', 'tag': 'CIS-5.1.4'}}, {'/etc/inetd.conf': {'pattern': '^ntalk', 'tag': 'CIS-5.1.4'}}]}, 'description': 'Ensure talk server is not enabled'}}}}
        data_list = [dest, upd]
        for data in data_list:
            val = pulsar._dict_update(dest, data, recursive_update=True, merge_lists=True)
        assert (len(val['data']['blacklist'])) == 2

    def test_process(self):
        configfile = 'tests/unittests/resources/hubblestack_pulsar_config.yaml'
        verbose = False

        def config_get(value, default):
            return default
        __salt__ = {}
        __salt__['config.get'] = config_get
        pulsar.__salt__ = __salt__
        pulsar.__opts__ = {}
        var = pulsar.process(configfile, verbose)
        pulsar.__salt__ = {}
        assert len(var) == 0
        assert isinstance(var, list)

    def test_top_result_for_list(self):
        topfile = 'tests/unittests/resources/top.pulsar'

        def cp_cache_file(value):
            return 'tests/unittests/resources/top.pulsar'

        def match_compound(value):
            return value
        __salt__ = {}
        __salt__['cp.cache_file'] = cp_cache_file
        __salt__['match.compound'] = match_compound
        pulsar.__salt__ = __salt__
        get_top_data_config = pulsar.get_top_data(topfile)
        configs = ['salt://hubblestack_pulsar/' + config.replace('.', '/') + '.yaml'
                   for config in get_top_data_config]
        assert configs[0] == 'salt://hubblestack_pulsar/hubblestack_pulsar_config.yaml'

    def test_get_top_data(self):
        topfile = 'tests/unittests/resources/top.pulsar'

        def cp_cache_file(topfile):
            return topfile

        def match_compound(value):
            return value
        __salt__ = {}
        __salt__['cp.cache_file'] = cp_cache_file
        __salt__['match.compound'] = match_compound
        pulsar.__salt__ = __salt__
        result = pulsar.get_top_data(topfile)
        pulsar.__salt__ = {}
        assert isinstance(result, list)
        assert result[0] == 'hubblestack_pulsar_config'

    def test_get_top_data_for_CommandExecutionError(self):
        topfile = '/testfile'

        def cp_cache_file(topfile):
            return '/testfile'

        def match_compound(value):
            return value
        __salt__ = {}
        __salt__['cp.cache_file'] = cp_cache_file