# coverage run -m pytest -rA tests/test_configurator.py --no-header --html=./reports/pytest/report.html --self-contained-html && coverage html #noqa E501

import copy
import pytest

from wox.configurator import configuration_creation, session_setup
from wox.wox_exceptions import NoTaskError
from wox.wox_steward import WoxSteward


# python -B -m pytest -rA -k "test_configuration_creation"
def test_configuration_creation(monkeypatch, subtests, wox_toml_path):
    """
        Each environment configuration must be correctly built from
        wox.toml, applying its specific parameters when defined, or
        falling back to default settings otherwise.

        Environment-specific parameters must not propagate to other
        environments.
    """

    control_configs = {
        'testing': {
            'py36': {
                'deps': [
                    'pytest-7.0.1-py3-none-any.whl',
                    'tomli-1.2.3-py3-none-any.whl',
                ],
                'commands': ['python -B -m pytest'],
            },
            'default': {
                'deps': ['pytest'],
                'commands': ['python -B -m pytest'],
            },
        },
        'doc': {
            'default': {
                'deps': ['furo'],
                'commands': [
                    'python -m sphinx.cmd.quickstart docs --sep -q -p tuto -a wbarillon'
                ],
            }
        },
        'pixegami-hello': {
            'default': {
                'deps': ['pixegami-hello==0.3.0'],
                'commands': ['pixegami-hello'],
            }
        },
        'benchmark': {
            'py314': {
                'python_build': '~/python313/bin/python3'
            },
            'py313-dev': {
                'python_build': '~/python313-optim/bin/python3'
            },
            'py313-prod': {
                'python_build': '~/python313-prod/bin/python3'
            },
            'py313-control': {
                'python_build': '~/python313/bin/python3'
            }
        }
    }

    monkeypatch.setattr(WoxSteward, 'wox_toml', wox_toml_path)

    wox_data = WoxSteward().wox_data

    wox_configuration = wox_data.pop('wox_configuration') #noqa F841

    for task, settings in wox_data.items():

        envlist = wox_data[task].pop('envlist')

        for env in envlist:

            config = configuration_creation(env, settings, envlist)

            with subtests.test(task = task, env = env):
                assert config == control_configs[task][env], (
                    f"Configuration mismatch for task '{task}' and environment '{env}'.\
                    \n"
                )

class TestSessionSetup:
    """
        session_setup() must handle conflicts between wox_session_default, ``--task`` and
        ``exclude-task`` following requirements in Notes section of session_setup.
    """

    wox_configuration_with_wox_session_default = {
        'wox_configuration': {
            'recreate_envs': True,
            'wox_session_default': ['cowsay', 'testing']
        },
        'testing': {},
        'cowsay': {},
        'pixegami': {},
        'bash': {},
        'doc': {}
    }
    wox_configuration_without_wox_session_default = {
        'wox_configuration': {'recreate_envs': True},
        'testing': {},
        'cowsay': {},
        'pixegami': {},
        'bash': {},
        'doc': {}
    }

    test_session_setup_cases = [
        # wox
        (
            {'verbose': False, 'task': None, 'exclude_task': None},
            wox_configuration_without_wox_session_default,
            ['testing', 'cowsay', 'pixegami', 'bash', 'doc']
        ),
        # wox with wox_session_default
        (
            {'verbose': False, 'task': None, 'exclude_task': None},
            wox_configuration_with_wox_session_default,
            ['testing', 'cowsay']
        ),
        # wox --task doc without wox_session_default
        (
            {'verbose': False, 'task': ['doc'], 'exclude_task': None},
            wox_configuration_without_wox_session_default,
            ['doc']
        ),
        # wox --task doc with wox_session_default
        (
            {'verbose': False, 'task': ['doc'], 'exclude_task': None},
            wox_configuration_with_wox_session_default,
            ['doc']
        ),
        # wox --exclude-task cowsay bash without wox_session_default
        (
            {'verbose': False, 'task': None, 'exclude_task': ['cowsay', 'bash']},
            wox_configuration_without_wox_session_default,
            ['testing', 'pixegami', 'doc']
        ),
        # wox --exclude-task cowsay with wox_session_default
        (
            {'verbose': False, 'task': None, 'exclude_task': ['cowsay']},
            wox_configuration_with_wox_session_default,
            ['testing']
        ),
        # wox --task pixegami bash --exclude-task bash
        (
            {'verbose': False, 'task': ['pixegami', 'bash'], 'exclude_task': ['bash']},
            wox_configuration_with_wox_session_default,
            ['pixegami']
        )
    ]

    # python -B -m pytest -rA -k "test_session_setup"
    @pytest.mark.parametrize('cli_options, wox_data, expected', test_session_setup_cases)
    def test_session_setup(self, cli_options, wox_data, expected):

        wox_data = copy.deepcopy(wox_data)

        wox_configuration, wox_data = session_setup(cli_options, wox_data)

        assert list(wox_data) == expected

class TestNoTaskError:
    """
        session_setup() must raise NoTaskError when ``--task`` and ``--exclude-task``
        have the same tasks.
    """

    test_no_task_error_cases = [
        # wox --task pixegami --exclude-task pixegami
        (
            {'verbose': False, 'task': ['pixegami'], 'exclude_task': ['pixegami']},
            {'wox_configuration': {'recreate_envs': True},
                'testing': {},
                'cowsay': {},
                'pixegami': {},
                'bash': {},
                'doc': {}
            }
        ),
        # wox --task testing --exclude-task testing with wox_session_default
        (
            {'verbose': False, 'task': ['testing'], 'exclude_task': ['testing']},
            {'wox_configuration': {
                'recreate_envs': True,
                'wox_session_default': ['cowsay', 'testing']
                },
                'testing': {},
                'cowsay': {},
                'pixegami': {},
                'bash': {},
                'doc': {}
            }
        ),
        # wox --exclude-task cowsay testing with wox_session_default
        (
            {'verbose': False, 'task': None, 'exclude_task': ['cowsay', 'testing']},
            {'wox_configuration': {
                'recreate_envs': True,
                'wox_session_default': ['cowsay', 'testing']
                },
                'testing': {},
                'cowsay': {},
                'pixegami': {},
                'bash': {},
                'doc': {}
            }
        )
    ]

    # python -B -m pytest -rA -k "test_no_task_error"
    @pytest.mark.parametrize('cli_options, wox_data', test_no_task_error_cases)
    def test_no_task_error(self, cli_options, wox_data):

        wox_data = copy.deepcopy(wox_data)

        with pytest.raises(NoTaskError):
            wox_configuration, wox_data = session_setup(cli_options, wox_data)
