"""
Configuration hooks for `pytest`. Normally this wouldn't be necessary,
but since `pytest-codeblock` is used, we want to clean-up files generated by
running documentation tests. Therefore, this hook, which simply
calls the `clean_up` method of the `FILE_REGISTRY` instance.
"""

import functools
import shutil
import tempfile

from fake import FILE_REGISTRY
from moto import mock_aws
from pathy import use_fs
from pytest_codeblock.constants import CODEBLOCK_MARK

__author__ = "Artur Barseghyan <artur.barseghyan@gmail.com>"
__copyright__ = "2024-2025 Artur Barseghyan"
__license__ = "MIT"
__all__ = (
    "pytest_runtest_teardown",
    "pytest_collection_modifyitems",
)


def mock_google_cloud_storage(test_fn):
    """
    Decorator to redirect pathy.gs:// calls to a fresh local sandbox.

    - Creates a tempdir via tempfile.mkdtemp()
    - Calls use_fs(root) so Pathy maps gs://… to that folder
    - Runs the test
    - Cleans up the tempdir afterward
    """

    @functools.wraps(test_fn)
    def wrapper(*args, **kwargs):
        # Create an isolated root directory
        root = tempfile.mkdtemp(prefix="pathy_gcs_")
        try:
            # Tell Pathy to use local FS under our tempdir
            use_fs(root)

            # Run the actual test function
            return test_fn(*args, **kwargs)

        finally:
            # Clean up the entire sandbox
            shutil.rmtree(root, ignore_errors=True)

    return wrapper


mock_azure_cloud_storage = mock_google_cloud_storage


def pytest_collection_modifyitems(config, items):
    """Modify test item during collection."""
    for item in items:
        if item.get_closest_marker("aws"):
            # Apply `mock_aws` to all tests marked as `aws`
            item.obj = mock_aws(item.obj)
        if item.get_closest_marker("google_cloud_storage"):
            # Apply `mock_google_cloud_storage` to all tests marked
            # as `google_cloud_storage`
            item.obj = mock_google_cloud_storage(item.obj)
        if item.get_closest_marker("azure_cloud_storage"):
            # Apply `mock_azure_cloud_storage` to all tests marked
            # as `azure_cloud_storage`
            item.obj = mock_azure_cloud_storage(item.obj)


def pytest_runtest_teardown(item, nextitem):
    """Clean up after test ends."""
    if item.get_closest_marker(CODEBLOCK_MARK):
        FILE_REGISTRY.clean_up()
