import pytest

from shelfai.core.chunker import prefilter
from shelfai.core.compactor import compact_heuristic
from shelfai.core.shelf import Shelf


def test_list_files_supports_nested_categories_and_skips_hidden(shelf_dir):
    backup_dir = shelf_dir / ".shelfai" / "backups" / "abc123"
    backup_dir.mkdir(parents=True)
    (backup_dir / "ghost.md").write_text("# hidden backup", encoding="utf-8")

    generated_dir = shelf_dir / "generated" / "review" / "new_context"
    generated_dir.mkdir(parents=True)
    (generated_dir / "proposal.md").write_text("# staged proposal", encoding="utf-8")

    shelf = Shelf(str(shelf_dir))

    assert shelf.list_files(["memory/user"]) == ["memory/user/preferences.md"]
    all_files = shelf.list_files()
    assert "memory/user/preferences.md" in all_files
    assert not any(path.startswith(".shelfai/") for path in all_files)
    assert not any(path.startswith("generated/") for path in all_files)


def test_read_file_blocks_path_traversal(shelf_dir):
    shelf = Shelf(str(shelf_dir))
    with pytest.raises(ValueError):
        shelf.read_file("../outside.md")


def test_prefilter_preserves_remaining_sections(tmp_path):
    agent_file = tmp_path / "AGENT.md"
    agent_file.write_text(
        "# Example Agent\n\n"
        "## Rules\n"
        "- Be safe.\n\n"
        "## Workflow\n"
        "Do the task-specific work here.\n",
        encoding="utf-8",
    )

    result = prefilter(agent_file)

    assert "rules" in result.chunks
    assert "remaining" in result.chunks
    assert "Workflow" in result.chunks["remaining"]["content"]


def test_prefilter_handles_files_without_h2_sections(tmp_path):
    agent_file = tmp_path / "AGENT.md"
    agent_file.write_text("# Example Agent\n\nDo the work.\n", encoding="utf-8")

    result = prefilter(agent_file)

    assert "remaining" in result.chunks
    assert result.chunks["remaining"]["content"].startswith("# Example Agent")


def test_compactor_removes_placeholder_bullets(tmp_path):
    memory_file = tmp_path / "lessons.md"
    memory_file.write_text(
        "## Agent Lessons\n"
        "- _(pending review)_\n"
        "- Keep this item.\n",
        encoding="utf-8",
    )

    result = compact_heuristic(memory_file)

    assert result.removed_placeholders == 1
    assert "pending review" not in result.content
    assert "Keep this item." in result.content


def test_session_new_context_stages_by_default(shelf_dir):
    """New context files should be staged for review, not written directly."""
    from shelfai.agents.session import Extraction, SessionManager
    from shelfai.providers import LLMProvider

    class DummyProvider(LLMProvider):
        def complete(self, system: str, user: str, max_tokens: int = 4096) -> str:
            return "{}"

    shelf = Shelf(str(shelf_dir))
    manager = SessionManager(shelf, DummyProvider())

    extraction = Extraction(
        new_context=[
            {
                "suggested_path": "memory/agent/new-playbook.md",
                "suggested_abstract": "Playbook for handling deployment failures and rollback procedures",
                "content_summary": "Test staged content for deployment playbook",
            }
        ]
    )

    manager._apply_changes(extraction, "test-session")

    # File should NOT be created directly at the suggested path
    assert not (shelf_dir / "memory" / "agent" / "new-playbook.md").exists()
    # Should be staged under generated/review/new_context/
    staged_dir = shelf_dir / "generated" / "review" / "new_context"
    staged_files = list(staged_dir.rglob("*.md")) if staged_dir.exists() else []
    assert len(staged_files) == 1
    # Index should NOT have an entry for the suggested path
    assert shelf.index.get("memory/agent/new-playbook.md") is None
