import pytest
from pathlib import Path
from unittest.mock import patch

from integrator.app.integrate_mp import (
    _is_cvmfs_package,
    determine_environment_parameters,
)

# ---------------------------- #
# Tests for _is_cvmfs_package  #
# ---------------------------- #


def test_is_cvmfs_package_true():
    assert _is_cvmfs_package(
        "/cvmfs/tomo.esrf.fr/software/packages/ubuntu24.04/x86_64/tomotools/stable",
    )


def test_is_cvmfs_package_false_non_cvmfs():
    assert not _is_cvmfs_package("/home/user/integrator")


def test_is_cvmfs_package_false_missing_packages():
    assert not _is_cvmfs_package("/cvmfs/")


# ------------------------------------------- #
# Tests for determine_environment_parameters  #
# ------------------------------------------- #


def test_determine_env_cvmfs_module():
    python_path = "/cvmfs/tomo.esrf.fr/software/packages/ubuntu24.04/x86_64/tomotools/stable/bin/python"

    activate_path, activate_text = determine_environment_parameters(python_path)

    cvmfs_module_path = Path(
        "/cvmfs/tomo.esrf.fr/software/modules/ubuntu24.04/x86_64/tomotools/stable",
    )

    assert activate_path == cvmfs_module_path
    assert activate_text == f"""# Load CVMFS module\nmodule load {cvmfs_module_path}"""


def test_determine_env_virtualenv():
    python_path = "/home/user/.venv/bin/python"

    def fake_ending(path):
        return Path(path) == Path("/home/user/.venv/bin/activate")

    with patch(
        "integrator.app.integrate_mp.Path.is_file",
        autospec=True,
        side_effect=fake_ending,
    ):
        activate_path, activate_text = determine_environment_parameters(python_path)

    expected_path = Path(python_path).parent.parent / "bin" / "activate"

    assert activate_path == expected_path
    assert (
        activate_text == f"""# Initialize virtual environment\nsource {expected_path}"""
    )


def test_determine_conda_base_env():
    python_path = "/home/user/miniconda3/bin/python"

    def fake_ending(path):
        return str(path).endswith("etc/profile.d/conda.sh")

    with patch(
        "integrator.app.integrate_mp.Path.is_file",
        autospec=True,
        side_effect=fake_ending,
    ):
        activate_path, activate_text = determine_environment_parameters(python_path)

    expected_path = Path(python_path).parent.parent / "etc" / "profile.d" / "conda.sh"

    assert activate_path == expected_path
    assert (
        activate_text
        == f"""# Initialize conda\nsource {expected_path}\nconda activate base"""
    )


def test_determine_conda_named_env():
    python_path = "/home/user/miniconda3/envs/testenv/bin/python"

    def fake_is_file(path):
        # Only the parent conda.sh exists
        return "miniconda3/etc/profile.d/conda.sh" in str(path)

    with patch(
        "integrator.app.integrate_mp.Path.is_file",
        autospec=True,
        side_effect=fake_is_file,
    ):
        activate_path, activate_text = determine_environment_parameters(python_path)

    expected_path = Path(python_path).parents[3] / "etc" / "profile.d" / "conda.sh"
    env_name = Path(python_path).parents[1].name

    assert activate_path == expected_path
    assert (
        activate_text
        == f"""# Initialize conda\nsource {expected_path}\nconda activate {env_name}"""
    )


def test_determine_env_unknown_environment():
    python_path = "/home/user/bin/python"

    with (
        patch("integrator.app.integrate_mp.Path.is_file", return_value=False),
        pytest.raises(
            ValueError,
            match="Unknown environment type for python executable",
        ),
    ):
        determine_environment_parameters(python_path)
