"""Pytest configuration and fixtures."""

import contextlib  # only for deprecated items
import os  # only for deprecated items
from collections.abc import Iterator
from pathlib import Path
from shutil import copytree  # only for deprecated items
from tempfile import TemporaryDirectory
from unittest.mock import patch  # only for deprecated items

import pytest

from lsst.rsp.startup._deprecated.storage.command import Command


@pytest.fixture
def discovery_v1_path() -> Path:
    return Path(__file__).parent / "data" / "discovery" / "v1.json"


# Things for startup


@pytest.fixture
def _rsp_env(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
    with TemporaryDirectory() as fake_root:
        file_dir = Path(__file__).parent / "data" / "files"
        t_home = Path(fake_root) / "home" / "hambone"
        t_home.mkdir(parents=True)
        homedir = str(t_home)
        t_start = Path(fake_root) / "lab_startup"
        t_start.mkdir()
        monkeypatch.setenv(
            "NUBLADO_RUNTIME_MOUNTS_DIR", str(file_dir / "etc" / "nublado")
        )
        monkeypatch.setenv(
            "JUPYTERLAB_CONFIG_DIR", str(file_dir / "jupyterlab")
        )
        monkeypatch.setenv("RSP_STARTUP_PATH", f"{t_start!s}")
        monkeypatch.setenv("HOME", homedir)
        yield


# Things for deprecated startup


@pytest.fixture
def _deprecated_rsp_paths(monkeypatch: pytest.MonkeyPatch) -> Iterator[None]:
    # For each of these, we want to cover both the "from ..constants import"
    # and the "import lsst.rsp.constants" case.
    #
    # Only for use with the deprecated startup code.
    with patch(
        "lsst.rsp.startup._deprecated.services.labrunner.labrunner.ETC_PATH",
        (Path(__file__).parent / "data" / "files" / "etc"),
    ):
        with patch(
            "lsst.rsp.startup._deprecated.constants.ETC_PATH",
            (Path(__file__).parent / "data" / "files" / "etc"),
        ):
            yield


@pytest.fixture
def _deprecated_rsp_env(
    monkeypatch: pytest.MonkeyPatch,
    _deprecated_rsp_paths: None,
) -> Iterator[None]:
    with contextlib.suppress(KeyError):
        monkeypatch.delenv("TMPDIR")
        monkeypatch.delenv("DAF_BUTLER_CACHE_DIRECTORY")
    with TemporaryDirectory() as fake_root:
        t_home = Path(fake_root) / "home" / "hambone"
        file_dir = Path(__file__).parent / "data" / "files"
        template = file_dir / "homedir"
        homedir = str(t_home)
        monkeypatch.setenv("HOME", homedir)
        monkeypatch.setenv("USER", "hambone")
        monkeypatch.setenv("JUPYTERHUB_BASE_URL", "/nb/")
        monkeypatch.setenv(
            "NUBLADO_RUNTIME_MOUNTS_DIR", str(file_dir / "etc" / "nublado")
        )
        monkeypatch.setenv(
            "JUPYTERLAB_CONFIG_DIR", str(file_dir / "jupyterlab")
        )
        copytree(
            template,
            homedir,
            dirs_exist_ok=True,
            symlinks=True,
        )
        t_scratch = Path(fake_root) / "scratch"
        t_scratch.mkdir()
        monkeypatch.setenv("SCRATCH_PATH", str(t_scratch))
        yield


@pytest.fixture
def _deprecated_git_repo() -> Iterator[Path]:
    with TemporaryDirectory() as repo_str:
        pwd = Path.cwd()
        repo = Path(repo_str)
        os.chdir(repo)
        cmd = Command()
        cmd.run("git", "init")
        (repo / "README.md").write_text("# Test Repo\n")
        cmd.run("git", "config", "user.email", "hambone@opera.borphee.quendor")
        cmd.run("git", "config", "user.name", "Hambone")
        cmd.run("git", "config", "init.defaultBranch", "main")
        cmd.run("git", "checkout", "-b", "main")
        cmd.run("git", "add", "README.md")
        cmd.run("git", "commit", "-am", "Initial Commit")
        os.chdir(pwd)
        yield Path(repo)


# Things for deprecated landing page
@pytest.fixture(scope="session")
def _deprecated_monkeysession() -> Iterator[pytest.MonkeyPatch]:
    """MonkeyPatch, but session-scoped."""
    mpatch = pytest.MonkeyPatch()
    yield mpatch
    mpatch.undo()


@pytest.fixture(scope="session")
def _deprecated_init_container_fake_root(
    _deprecated_monkeysession: pytest.MonkeyPatch,
) -> Iterator[None]:
    with TemporaryDirectory() as td:
        contents = {
            "hello.txt": "Hello, world!\n",
            "goodbye.txt": "Goodbye, cruel world.\n",
        }
        tutorial_directory = Path(td) / "tutorials"
        tutorial_directory.mkdir(parents=True)
        for fn, text in contents.items():
            out_file = tutorial_directory / fn
            out_file.write_text(text)
        home_directory = Path(td) / "home" / "gregorsamsa"
        home_directory.mkdir(parents=True)

        _deprecated_monkeysession.setenv("NUBLADO_HOME", str(home_directory))
        _deprecated_monkeysession.setenv(
            "CST_LANDING_PAGE_SRC_DIR", str(tutorial_directory)
        )
        _deprecated_monkeysession.setenv(
            "CST_LANDING_PAGE_TGR_DIR", "notebooks/tutorials"
        )
        _deprecated_monkeysession.setenv(
            "CST_LANDING_PAGE_FILES", "hello.txt", "goodbye.txt"
        )
        yield
