"""Tests for llmhosts uninstall command."""

from __future__ import annotations

import pytest


@pytest.mark.unit
class TestUninstall:
    """Unit tests for the uninstall function."""

    def test_removes_data_dir(self, tmp_path) -> None:
        """Uninstall removes the main data directory (~/.llmhosts)."""
        from llmhosts.uninstall import uninstall

        data_dir = tmp_path / ".llmhosts"
        data_dir.mkdir(parents=True)
        (data_dir / "config.toml").write_text("[server]\nport = 11400\n")
        (data_dir / "llmhosts.db").write_bytes(b"sqlite")

        result = uninstall(
            data_dir=str(data_dir),
            config_dir=str(tmp_path / ".config" / "llmhosts"),
            models_dir=str(data_dir / "models"),
            confirm=False,
        )

        assert not data_dir.exists()
        assert result["data"] is True

    def test_removes_config_dir(self, tmp_path) -> None:
        """Uninstall removes the XDG config directory (~/.config/llmhosts)."""
        from llmhosts.uninstall import uninstall

        config_dir = tmp_path / ".config" / "llmhosts"
        config_dir.mkdir(parents=True)
        tls_dir = config_dir / "tls"
        tls_dir.mkdir()
        (tls_dir / "ca.pem").write_bytes(b"cert")

        result = uninstall(
            data_dir=str(tmp_path / ".llmhosts"),
            config_dir=str(config_dir),
            models_dir=str(tmp_path / ".llmhosts" / "models"),
            confirm=False,
        )

        assert not config_dir.exists()
        assert result["config"] is True

    def test_keeps_models_without_all_flag(self, tmp_path) -> None:
        """Without --all, models directory is preserved."""
        from llmhosts.uninstall import uninstall

        models_dir = tmp_path / "models"
        models_dir.mkdir()
        (models_dir / "test.gguf").write_bytes(b"model data")

        result = uninstall(
            data_dir=str(tmp_path / "data"),
            config_dir=str(tmp_path / "config"),
            models_dir=str(models_dir),
            confirm=False,
            remove_all=False,
        )

        assert models_dir.exists()
        assert (models_dir / "test.gguf").exists()
        assert result["models"] is False

    def test_removes_models_with_all_flag(self, tmp_path) -> None:
        """With --all, models directory is removed."""
        from llmhosts.uninstall import uninstall

        models_dir = tmp_path / "models"
        models_dir.mkdir()
        (models_dir / "test.gguf").write_bytes(b"model data")

        result = uninstall(
            data_dir=str(tmp_path / "data"),
            config_dir=str(tmp_path / "config"),
            models_dir=str(models_dir),
            confirm=False,
            remove_all=True,
        )

        assert not models_dir.exists()
        assert result["models"] is True

    def test_handles_missing_dirs_gracefully(self, tmp_path) -> None:
        """Uninstall does not raise when directories do not exist."""
        from llmhosts.uninstall import uninstall

        result = uninstall(
            data_dir=str(tmp_path / "nonexistent_data"),
            config_dir=str(tmp_path / "nonexistent_config"),
            models_dir=str(tmp_path / "nonexistent_models"),
            confirm=False,
            remove_all=True,
        )

        assert result["data"] is False
        assert result["config"] is False
        assert result["models"] is False

    def test_returns_correct_result_dict(self, tmp_path) -> None:
        """Result dict reports what was actually removed."""
        from llmhosts.uninstall import uninstall

        data_dir = tmp_path / ".llmhosts"
        data_dir.mkdir()
        config_dir = tmp_path / ".config" / "llmhosts"
        # config_dir intentionally not created

        result = uninstall(
            data_dir=str(data_dir),
            config_dir=str(config_dir),
            models_dir=str(data_dir / "models"),
            confirm=False,
        )

        assert result["data"] is True
        assert result["config"] is False
        assert result["models"] is False

    def test_removes_nested_data(self, tmp_path) -> None:
        """Uninstall recursively removes nested data files."""
        from llmhosts.uninstall import uninstall

        data_dir = tmp_path / ".llmhosts"
        data_dir.mkdir()
        cache_dir = data_dir / "cache" / "vcache"
        cache_dir.mkdir(parents=True)
        (cache_dir / "index.bin").write_bytes(b"cache data")
        (data_dir / "config.toml").write_text("[server]\nport = 4000\n")

        result = uninstall(
            data_dir=str(data_dir),
            config_dir=str(tmp_path / "config"),
            models_dir=str(data_dir / "models"),
            confirm=False,
        )

        assert not data_dir.exists()
        assert result["data"] is True

    def test_models_inside_data_dir_kept_without_all(self, tmp_path) -> None:
        """When models_dir is inside data_dir, --all=False preserves models.

        The uninstall function removes data_dir but extracts models_dir first
        if it exists and remove_all is False.
        """
        from llmhosts.uninstall import uninstall

        data_dir = tmp_path / ".llmhosts"
        models_dir = data_dir / "models"
        models_dir.mkdir(parents=True)
        (models_dir / "llama.gguf").write_bytes(b"model")
        (data_dir / "config.toml").write_text("[server]\n")

        result = uninstall(
            data_dir=str(data_dir),
            config_dir=str(tmp_path / "config"),
            models_dir=str(models_dir),
            confirm=False,
            remove_all=False,
        )

        # Config/cache inside data_dir removed
        assert not (data_dir / "config.toml").exists()
        # Models preserved
        assert models_dir.exists()
        assert (models_dir / "llama.gguf").exists()
        assert result["data"] is True
        assert result["models"] is False

    def test_keep_data_preserves_everything(self, tmp_path) -> None:
        """keep_data=True preserves data, config, and models."""
        from llmhosts.uninstall import uninstall

        data_dir = tmp_path / ".llmhosts"
        data_dir.mkdir()
        (data_dir / "config.toml").write_text("test = true")
        config_dir = tmp_path / ".config" / "llmhosts"
        config_dir.mkdir(parents=True)

        result = uninstall(
            data_dir=str(data_dir),
            config_dir=str(config_dir),
            models_dir=str(data_dir / "models"),
            confirm=False,
            keep_data=True,
        )

        assert data_dir.exists()
        assert config_dir.exists()
        assert result["data"] is False
        assert result["config"] is False
        assert result["models"] is False


@pytest.mark.unit
class TestUninstallDefaults:
    """Verify default path constants are sensible."""

    def test_default_data_dir_contains_llmhosts(self) -> None:
        from llmhosts.uninstall import _DEFAULT_DATA_DIR

        assert ".llmhosts" in _DEFAULT_DATA_DIR or "llmhosts" in _DEFAULT_DATA_DIR

    def test_default_models_dir_inside_data_dir(self) -> None:
        from llmhosts.uninstall import _DEFAULT_DATA_DIR, _DEFAULT_MODELS_DIR

        assert _DEFAULT_MODELS_DIR.startswith(_DEFAULT_DATA_DIR)
