# -*- coding: utf-8 -*-

import pytest

from freezegun import freeze_time


PYTEST_VERSION = tuple(int(part) for part in pytest.__version__.split('.'))
MARKER_NAME = 'freeze_time'
FIXTURE_NAME = 'freezer'


def get_closest_marker(node, name):
    """
    Get our marker, regardless of pytest version
    """
    if PYTEST_VERSION < (3, 6, 0):
        return node.get_marker('freeze_time')
    else:
        return node.get_closest_marker('freeze_time')


@pytest.fixture(name=FIXTURE_NAME)
def freezer_fixture(request):
    """
    Freeze time and make it available to the test
    """
    args = []
    kwargs = {}
    ignore = []

    # If we've got a marker, use the arguments provided there
    marker = get_closest_marker(request.node, MARKER_NAME)
    if marker:
        ignore = marker.kwargs.pop('ignore', [])
        args = marker.args
        kwargs = marker.kwargs

    # Always want to ignore _pytest
    ignore.append('_pytest.terminal')
    ignore.append('_pytest.runner')

    # Freeze time around the test
    freezer = freeze_time(*args, ignore=ignore, **kwargs)
    frozen_time = freezer.start()
    yield frozen_time
    freezer.stop()


def pytest_collection_modifyitems(items):
    """
    Inject our fixture into any tests with our marker
    """
    for item in items:
        if (
            get_closest_marker(item, MARKER_NAME)
            and FIXTURE_NAME not in item.fixturenames
        ):
            item.fixturenames.insert(0, FIXTURE_NAME)


def pytest_configure(config):
    """
    Register our marker
    """
    config.addinivalue_line(
        "markers", "{}(...): use freezegun to freeze time".format(MARKER_NAME)
    )