import warnings

import pytest

from leapp.libraries.actor.systemfacts import get_selinux_status
from leapp.models import SELinuxFacts

no_selinux = False
try:
    import selinux
except ImportError:
    no_selinux = True
    warnings.warn(
        'Tests which uses `selinux` will be skipped'
        ' due to library unavailability.', ImportWarning)


reason_to_skip_msg = "Selinux is not available"

# FIXME: create valid tests...


@pytest.mark.skipif(no_selinux, reason=reason_to_skip_msg)
def test_selinux_enabled_enforcing(monkeypatch):
    """
    Test case SELinux is enabled in enforcing mode
    """
    monkeypatch.setattr(selinux, 'is_selinux_mls_enabled', lambda: 1)
    monkeypatch.setattr(selinux, 'security_getenforce', lambda: 1)
    monkeypatch.setattr(selinux, 'selinux_getenforcemode', lambda: [0, 1])
    monkeypatch.setattr(selinux, 'is_selinux_enabled', lambda: 1)
    monkeypatch.setattr(selinux, 'selinux_getpolicytype', lambda: [0, 'targeted'])
    expected_data = {'policy': 'targeted',
                     'mls_enabled': True,
                     'enabled': True,
                     'runtime_mode': 'enforcing',
                     'static_mode': 'enforcing'}
    assert SELinuxFacts(**expected_data) == get_selinux_status()


@pytest.mark.skipif(no_selinux, reason=reason_to_skip_msg)
def test_selinux_enabled_permissive(monkeypatch):
    """
    Test case SELinux is enabled in permissive mode
    """
    monkeypatch.setattr(selinux, 'is_selinux_mls_enabled', lambda: 1)
    monkeypatch.setattr(selinux, 'security_getenforce', lambda: 0)
    monkeypatch.setattr(selinux, 'selinux_getenforcemode', lambda: [0, 0])
    monkeypatch.setattr(selinux, 'is_selinux_enabled', lambda: 1)
    monkeypatch.setattr(selinux, 'selinux_getpolicytype', lambda: [0, 'targeted'])
    expected_data = {'policy': 'targeted',
                     'mls_enabled': True,
                     'enabled': True,
                     'runtime_mode': 'permissive',
                     'static_mode': 'permissive'}
    assert SELinuxFacts(**expected_data) == get_selinux_status()


@pytest.mark.skipif(no_selinux, reason=reason_to_skip_msg)
def test_selinux_disabled(monkeypatch):
    """
    Test case SELinux is disabled
    """
    monkeypatch.setattr(selinux, 'is_selinux_mls_enabled', lambda: 0)
    monkeypatch.setattr(selinux, 'security_getenforce', lambda: 0)
    monkeypatch.setattr(selinux, 'selinux_getenforcemode', lambda: [0, 0])
    monkeypatch.setattr(selinux, 'is_selinux_enabled', lambda: 0)
    monkeypatch.setattr(selinux, 'selinux_getpolicytype', lambda: [0, 'targeted'])
    expected_data = {'policy': 'targeted',
                     'mls_enabled': False,
                     'enabled': False,
                     'runtime_mode': 'permissive',
                     'static_mode': 'permissive'}
    assert SELinuxFacts(**expected_data) == get_selinux_status()


class MockNoConfigFileOSError(object):
    def __init__(self):
        raise OSError


@pytest.mark.skipif(no_selinux, reason=reason_to_skip_msg)
def test_selinux_disabled_no_config_file(monkeypatch):
    """
    Test case SELinux is disabled
    """
    monkeypatch.setattr(selinux, 'is_selinux_mls_enabled', lambda: 0)
    monkeypatch.setattr(selinux, 'security_getenforce', lambda: 0)
    monkeypatch.setattr(selinux, 'selinux_getenforcemode', MockNoConfigFileOSError)
    monkeypatch.setattr(selinux, 'is_selinux_enabled', lambda: 0)
    monkeypatch.setattr(selinux, 'selinux_getpolicytype', lambda: [0, 'targeted'])
    expected_data = {'policy': 'targeted',
                     'mls_enabled': False,
                     'enabled': False,
                     'runtime_mode': 'permissive',
                     'static_mode': 'disabled'}

    assert SELinuxFacts(**expected_data) == get_selinux_status()

[((436, 493), 'pytest.mark.skipif', 'pytest.mark.skipif', (['no_selinux'], {'reason': 'reason_to_skip_msg'}), '(no_selinux, reason=reason_to_skip_msg)\n', (454, 493), False, 'import pytest\n'), ((1261, 1318), 'pytest.mark.skipif', 'pytest.mark.skipif', (['no_selinux'], {'reason': 'reason_to_skip_msg'}), '(no_selinux, reason=reason_to_skip_msg)\n', (1279, 1318), False, 'import pytest\n'), ((2090, 2147), 'pytest.mark.skipif', 'pytest.mark.skipif', (['no_selinux'], {'reason': 'reason_to_skip_msg'}), '(no_selinux, reason=reason_to_skip_msg)\n', (2108, 2147), False, 'import pytest\n'), ((2980, 3037), 'pytest.mark.skipif', 'pytest.mark.skipif', (['no_selinux'], {'reason': 'reason_to_skip_msg'}), '(no_selinux, reason=reason_to_skip_msg)\n', (2998, 3037), False, 'import pytest\n'), ((225, 340), 'warnings.warn', 'warnings.warn', (['"""Tests which uses `selinux` will be skipped due to library unavailability."""', 'ImportWarning'], {}), "(\n    'Tests which uses `selinux` will be skipped due to library unavailability.'\n    , ImportWarning)\n", (238, 340), False, 'import warnings\n'), ((1204, 1233), 'leapp.models.SELinuxFacts', 'SELinuxFacts', ([], {}), '(**expected_data)\n', (1216, 1233), False, 'from leapp.models import SELinuxFacts\n'), ((1237, 1257), 'leapp.libraries.actor.systemfacts.get_selinux_status', 'get_selinux_status', ([], {}), '()\n', (1255, 1257), False, 'from leapp.libraries.actor.systemfacts import get_selinux_status\n'), ((2033, 2062), 'leapp.models.SELinuxFacts', 'SELinuxFacts', ([], {}), '(**expected_data)\n', (2045, 2062), False, 'from leapp.models import SELinuxFacts\n'), ((2066, 2086), 'leapp.libraries.actor.systemfacts.get_selinux_status', 'get_selinux_status', ([], {}), '()\n', (2084, 2086), False, 'from leapp.libraries.actor.systemfacts import get_selinux_status\n'), ((2836, 2865), 'leapp.models.SELinuxFacts', 'SELinuxFacts', ([], {}), '(**expected_data)\n', (2848, 2865), False, 'from leapp.models import SELinuxFacts\n'), ((2869, 2889), 'leapp.libraries.actor.systemfacts.get_selinux_status', 'get_selinux_status', ([], {}), '()\n', (2887, 2889), False, 'from leapp.libraries.actor.systemfacts import get_selinux_status\n'), ((3749, 3778), 'leapp.models.SELinuxFacts', 'SELinuxFacts', ([], {}), '(**expected_data)\n', (3761, 3778), False, 'from leapp.models import SELinuxFacts\n'), ((3782, 3802), 'leapp.libraries.actor.systemfacts.get_selinux_status', 'get_selinux_status', ([], {}), '()\n', (3800, 3802), False, 'from leapp.libraries.actor.systemfacts import get_selinux_status\n')]