import pytest

from test_migrations import constants

from .fixtures import migrator  # pylint: disable=W0611

pytest_plugins = ['pytest_django']  # pylint: disable=C0103


def pytest_load_initial_conftests(early_config):
    # Register the marks
    early_config.addinivalue_line(
        'markers',
        (
            "{marker}: Mark the test as a"
            "Django migration test. Dynamically add `transactional_db` "
            "fixture to marked item. Migration tests are run only when "
            "`--test-migrations` pytest's CLI option passed."
        ).format(marker=constants.MIGRATIONS_TEST_MARKER),
    )


def pytest_addoption(parser):
    """Add option for running migration tests.
    """
    group = parser.getgroup('django_test_migrations')
    group._addoption(  # pylint: disable=W0212
        '--test-migrations',
        action='store_true',
        dest='test_migrations',
        default=False,
        help=(
            "Run Django migration tests. This does the following: "
            " ensure migrations are enabled, skip all test not marked with "
            "`{marker}` marker."
        ).format(marker=constants.MIGRATIONS_TEST_MARKER)
    )


def pytest_sessionstart(session):
    if session.config.getoption('test_migrations', False):
        # TODO: consider raising AssertionError when `nomigration` falsy
        session.config.option.nomigrations = False


def pytest_collection_modifyitems(session, items):
    migration_test_skip_marker = pytest.mark.skip(
        reason=(
            'Migration tests not skipped, because`--test-migration` option '
            'passed.'
        ),
    )
    for item in items:
        # mark all tests using `migrator` fixture with `MIGRATION_TEST_MARKER`
        if 'migrator' in getattr(item, 'fixturenames', list()):
            item.add_marker(constants.MIGRATIONS_TEST_MARKER)
        # skip all no migration tests when option `--test-migrations` passed
        if (
                session.config.getoption('test_migrations', False)
                and not item.get_closest_marker(constants.MIGRATIONS_TEST_MARKER)
        ):
            item.add_marker(migration_test_skip_marker)


@pytest.fixture(autouse=True, scope='function')
def _django_migration_marker(request):
    """Implement the migration marker, internal to `django_test_migrations`.

    This will dynamically request the `transactional_db` fixture
    and skip tests marked with migration marker if not
    explicitly requested by passing `--test-migrations` option.
    """
    marker = request.node.get_closest_marker(constants.MIGRATIONS_TEST_MARKER)
    if marker:
        if request.config.getoption('test_migrations', False):
            request.getfixturevalue('transactional_db')
        else:
            pytest.skip(
                msg=(
                    'Migration tests can require `migrations` enabled and can '
                    'be slow hence they should be ran separetly with pytest '
                    '`--test-migrations` option.'
                ),
            )

import pytest

from test_migrations import constants

from .fixtures import migrator  # pylint: disable=W0611

pytest_plugins = ['pytest_django']  # pylint: disable=C0103


def pytest_load_initial_conftests(early_config):
    # Register the marks
    early_config.addinivalue_line(
        'markers',
        (
            "{marker}: Mark the test as a"
            "Django migration test. Dynamically add `transactional_db` "
            "fixture to marked item. Migration tests are run only when "
            "`--test-migrations` pytest's CLI option passed."
        ).format(marker=constants.MIGRATIONS_TEST_MARKER),
    )


def pytest_addoption(parser):
    """Add option for running migration tests.
    """
    group = parser.getgroup('django_test_migrations')
    group._addoption(  # pylint: disable=W0212
        '--test-migrations',
        action='store_true',
        dest='test_migrations',
        default=False,
        help=(
            "Run Django migration tests. This does the following: "
            " ensure migrations are enabled, skip all test not marked with "
            "`{marker}` marker."
        ).format(marker=constants.MIGRATIONS_TEST_MARKER)
    )


def pytest_sessionstart(session):
    if session.config.getoption('test_migrations', False):
        # TODO: consider raising AssertionError when `nomigration` falsy
        session.config.option.nomigrations = False


def pytest_collection_modifyitems(session, items):
    migration_test_skip_marker = pytest.mark.skip(
        reason=(
            'Migration tests not skipped, because`--test-migration` option '
            'passed.'
        ),
    )
    for item in items:
        # mark all tests using `migrator` fixture with `MIGRATION_TEST_MARKER`
        if 'migrator' in getattr(item, 'fixturenames', list()):
            item.add_marker(constants.MIGRATIONS_TEST_MARKER)
        # skip all no migration tests when option `--test-migrations` passed
        if (
                session.config.getoption('test_migrations', False)
                and not item.get_closest_marker(constants.MIGRATIONS_TEST_MARKER)
        ):
            item.add_marker(migration_test_skip_marker)


@pytest.fixture(autouse=True, scope='function')
def _django_migration_marker(request):
    """Implement the migration marker, internal to `django_test_migrations`.

    This will dynamically request the `transactional_db` fixture
    and skip tests marked with migration marker if not
    explicitly requested by passing `--test-migrations` option.
    """
    marker = request.node.get_closest_marker(constants.MIGRATIONS_TEST_MARKER)
    if marker:
        if request.config.getoption('test_migrations', False):
            request.getfixturevalue('transactional_db')
        else:
            pytest.skip(
                msg=(
                    'Migration tests can require `migrations` enabled and can '
                    'be slow hence they should be ran separetly with pytest '
                    '`--test-migrations` option.'
                ),
            )

# pylint: disable=W0611 # pylint: disable=C0103 # Register the marks Add option for running migration tests. # pylint: disable=W0212 # TODO: consider raising AssertionError when `nomigration` falsy # mark all tests using `migrator` fixture with `MIGRATION_TEST_MARKER` # skip all no migration tests when option `--test-migrations` passed Implement the migration marker, internal to `django_test_migrations`.      This will dynamically request the `transactional_db` fixture     and skip tests marked with migration marker if not     explicitly requested by passing `--test-migrations` option.