"""Tests for mission context builder.

Tests verify build_mission_context() and build_module_descriptions() from
llm/missions/context.py produce category-specific context strings for LLM
mission generation.
"""

from __future__ import annotations

from tests.conftest import make_analysis_result, make_briefing_result
from unfamiliar.analysis.models import (
    DetectedModule,
    EntryPoint,
    FileTestInfo,
    FunctionDef,
    ImportGraph,
    ParsedFile,
    ParsedImport,
    ScoredFile,
)
from unfamiliar.constants import DEFAULT_TOKEN_BUDGET, EntryType, InvestigationCategory
from unfamiliar.llm.briefing.schemas import ModuleDescription
from unfamiliar.llm.context import CHARS_PER_TOKEN
from unfamiliar.llm.missions.context import (
    build_mission_context,
    build_module_descriptions,
)


class TestBuildMissionContextArchitectureCategory:
    """Tests for build_mission_context() with ARCHITECTURE category."""

    def test_architecture_category_includes_architecture_keywords(self):
        """ARCHITECTURE category output includes architecture-relevant sections."""
        entry_points = [
            EntryPoint(
                file_path="src/main.py",
                entry_type=EntryType.MAIN,
                description="Application entry point",
                line=1,
            )
        ]
        import_graph = ImportGraph(
            edges={"src/utils.py": {"src/core.py"}},
            in_degree={"src/core.py": 5, "src/utils.py": 0},
        )
        languages = {"python": 10, "typescript": 5}

        analysis = make_analysis_result(
            entry_points=entry_points,
            import_graph=import_graph,
            languages=languages,
        )
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.ARCHITECTURE,
            previous_missions=[],
        )

        assert "## Files Relevant to Architecture" in result
        assert "## Architecture Context" in result
        assert "### Entry Points" in result
        assert "### Hub Files" in result
        assert "### Language Distribution" in result

    def test_architecture_category_shows_entry_point_details(self):
        """ARCHITECTURE category shows entry point file, line, and description."""
        entry_points = [
            EntryPoint(
                file_path="src/app.py",
                entry_type=EntryType.API_ROUTE,
                description="REST API handler",
                line=42,
            )
        ]
        analysis = make_analysis_result(entry_points=entry_points)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.ARCHITECTURE,
            previous_missions=[],
        )

        assert "src/app.py" in result
        assert "42" in result
        assert "api_route" in result
        assert "REST API handler" in result


class TestBuildMissionContextTestingCategory:
    """Tests for build_mission_context() with TESTING category."""

    def test_testing_category_includes_test_coverage_info(self):
        """TESTING category output includes test coverage information."""
        test_info = FileTestInfo(
            test_files={"tests/test_a.py", "tests/test_b.py"},
            untested_files={"src/orphan.py"},
            tier="basic",
        )
        analysis = make_analysis_result(test_info=test_info)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
        )

        assert "## Files Relevant to Testing" in result
        assert "## Testing Context" in result
        assert "Test files:" in result
        assert "Untested files:" in result

    def test_testing_category_lists_test_files(self):
        """TESTING category lists test files found in the codebase."""
        test_info = FileTestInfo(
            test_files={"tests/test_main.py", "tests/test_utils.py"},
            tier="basic",
        )
        analysis = make_analysis_result(test_info=test_info)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
        )

        assert "### Test Files" in result
        assert "tests/test_main.py" in result
        assert "tests/test_utils.py" in result

    def test_testing_category_shows_coverage_summary_for_enhanced_tier(self):
        """TESTING category shows coverage percentages in enhanced tier."""
        test_info = FileTestInfo(
            test_files={"tests/test_a.py"},
            tier="enhanced",
            coverage_summary={"src/core.py": 0.95, "src/utils.py": 0.50},
        )
        analysis = make_analysis_result(test_info=test_info)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
        )

        assert "### Coverage Summary" in result
        assert "src/core.py:" in result
        assert "95.0%" in result


class TestBuildMissionContextTechnicalDebtCategory:
    """Tests for build_mission_context() with TECHNICAL_DEBT category."""

    def test_technical_debt_category_includes_debt_info(self):
        """TECHNICAL_DEBT category output includes debt-relevant content."""
        parsed_files = {
            "src/complex.py": ParsedFile(
                path="src/complex.py",
                language="python",
                complexity=50,
                line_count=500,
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TECHNICAL_DEBT,
            previous_missions=[],
        )

        assert "## Files Relevant to Technical Debt" in result
        assert "## Technical Debt Context" in result

    def test_technical_debt_category_shows_high_complexity_files(self):
        """TECHNICAL_DEBT category shows files with high complexity."""
        parsed_files = {
            "src/complex.py": ParsedFile(
                path="src/complex.py",
                language="python",
                complexity=45,
                line_count=100,
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TECHNICAL_DEBT,
            previous_missions=[],
        )

        assert "### High Complexity Files" in result
        assert "src/complex.py" in result
        assert "complexity 45" in result

    def test_technical_debt_category_shows_large_files(self):
        """TECHNICAL_DEBT category shows files with many lines."""
        parsed_files = {
            "src/large.py": ParsedFile(
                path="src/large.py",
                language="python",
                complexity=10,
                line_count=500,
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TECHNICAL_DEBT,
            previous_missions=[],
        )

        assert "### Large Files" in result
        assert "src/large.py" in result
        assert "500 lines" in result


class TestBuildMissionContextDependenciesCategory:
    """Tests for build_mission_context() with DEPENDENCIES category."""

    def test_dependencies_category_includes_dependency_info(self):
        """DEPENDENCIES category output includes dependency-related content."""
        parsed_files = {
            "src/main.py": ParsedFile(
                path="src/main.py",
                language="python",
                imports=[
                    ParsedImport(
                        source_path="src/main.py",
                        target="requests",
                        is_relative=False,
                        names=["get"],
                    ),
                ],
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DEPENDENCIES,
            previous_missions=[],
        )

        assert "## Files Relevant to Dependencies" in result
        assert "## Dependencies Context" in result

    def test_dependencies_category_lists_external_packages(self):
        """DEPENDENCIES category lists external packages by import frequency."""
        parsed_files = {
            "src/a.py": ParsedFile(
                path="src/a.py",
                language="python",
                imports=[
                    ParsedImport(
                        source_path="src/a.py",
                        target="requests",
                        is_relative=False,
                        names=[],
                    ),
                ],
            ),
            "src/b.py": ParsedFile(
                path="src/b.py",
                language="python",
                imports=[
                    ParsedImport(
                        source_path="src/b.py",
                        target="requests",
                        is_relative=False,
                        names=[],
                    ),
                    ParsedImport(
                        source_path="src/b.py",
                        target="pydantic",
                        is_relative=False,
                        names=[],
                    ),
                ],
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DEPENDENCIES,
            previous_missions=[],
        )

        assert "### External Dependencies" in result
        assert "requests" in result


class TestBuildMissionContextDataFlowCategory:
    """Tests for build_mission_context() with DATA_FLOW category."""

    def test_data_flow_category_includes_import_relationships(self):
        """DATA_FLOW category includes import relationship information."""
        import_graph = ImportGraph(
            edges={
                "src/a.py": {"src/b.py"},
                "src/b.py": {"src/c.py"},
            },
            in_degree={"src/a.py": 0, "src/b.py": 1, "src/c.py": 1},
        )
        analysis = make_analysis_result(import_graph=import_graph)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DATA_FLOW,
            previous_missions=[],
        )

        assert "## Data Flow Context" in result
        assert "### Import Relationships" in result

    def test_data_flow_category_shows_data_processing_files(self):
        """DATA_FLOW category shows files with data transformation keywords."""
        scored_files = [
            ScoredFile(path="src/transform/user_transform.py", score=50, reasons=[]),
            ScoredFile(path="src/validators/data_validator.py", score=40, reasons=[]),
        ]
        analysis = make_analysis_result(scored_files=scored_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DATA_FLOW,
            previous_missions=[],
        )

        assert "### Data Processing Files" in result


class TestBuildMissionContextConventionsCategory:
    """Tests for build_mission_context() with CONVENTIONS category."""

    def test_conventions_category_includes_conventions_context(self):
        """CONVENTIONS category output includes conventions-relevant sections."""
        languages = {"python": 15, "typescript": 3}
        analysis = make_analysis_result(languages=languages)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.CONVENTIONS,
            previous_missions=[],
        )

        assert "## Conventions Context" in result
        assert "### Language Distribution" in result

    def test_conventions_category_shows_import_style(self):
        """CONVENTIONS category shows relative vs absolute import counts."""
        parsed_files = {
            "src/a.py": ParsedFile(
                path="src/a.py",
                language="python",
                imports=[
                    ParsedImport(
                        source_path="src/a.py", target=".utils", is_relative=True
                    ),
                    ParsedImport(
                        source_path="src/a.py",
                        target="unfamiliar.core",
                        is_relative=False,
                    ),
                ],
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.CONVENTIONS,
            previous_missions=[],
        )

        assert "### Import Style" in result
        assert "Relative imports:" in result

    def test_conventions_category_shows_function_prefixes(self):
        """CONVENTIONS category shows common function naming patterns."""

        parsed_files = {
            "src/handlers.py": ParsedFile(
                path="src/handlers.py",
                language="python",
                definitions=[
                    FunctionDef(
                        name="handle_request",
                        line_start=1,
                        line_end=10,
                        is_async=False,
                        kind="function",
                    ),
                    FunctionDef(
                        name="handle_response",
                        line_start=12,
                        line_end=20,
                        is_async=False,
                        kind="function",
                    ),
                    FunctionDef(
                        name="get_user",
                        line_start=22,
                        line_end=30,
                        is_async=False,
                        kind="function",
                    ),
                ],
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.CONVENTIONS,
            previous_missions=[],
        )

        assert "### Common Function Prefixes" in result
        assert "handle_" in result

    def test_conventions_category_shows_test_naming_patterns(self):
        """CONVENTIONS category shows test file naming conventions."""
        test_info = FileTestInfo(
            test_files={
                "tests/test_main.py",
                "tests/test_utils.py",
                "tests/api.spec.ts",
            },
            tier="basic",
        )
        analysis = make_analysis_result(test_info=test_info)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.CONVENTIONS,
            previous_missions=[],
        )

        assert "### Test File Naming" in result
        assert "test_*" in result

    def test_conventions_category_shows_top_level_organization(self):
        """CONVENTIONS category shows directory organization."""
        scored_files = [
            ScoredFile(path="src/core.py", score=50, reasons=[]),
            ScoredFile(path="src/utils.py", score=40, reasons=[]),
            ScoredFile(path="tests/test_core.py", score=30, reasons=[]),
        ]
        analysis = make_analysis_result(scored_files=scored_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.CONVENTIONS,
            previous_missions=[],
        )

        assert "### Top-Level Organization" in result
        assert "src/" in result


class TestBuildMissionContextDomainBusinessLogicCategory:
    """Tests for build_mission_context() with DOMAIN_BUSINESS_LOGIC category."""

    def test_domain_business_logic_includes_context_section(self):
        """DOMAIN_BUSINESS_LOGIC category output includes domain context section."""
        analysis = make_analysis_result()
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DOMAIN_BUSINESS_LOGIC,
            previous_missions=[],
        )

        assert "## Domain Business Logic Context" in result

    def test_domain_business_logic_shows_domain_files(self):
        """DOMAIN_BUSINESS_LOGIC shows files in domain-like directories."""
        scored_files = [
            ScoredFile(path="src/models/user.py", score=50, reasons=[]),
            ScoredFile(path="src/services/auth.py", score=40, reasons=[]),
            ScoredFile(path="src/core/engine.py", score=30, reasons=[]),
        ]
        analysis = make_analysis_result(scored_files=scored_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DOMAIN_BUSINESS_LOGIC,
            previous_missions=[],
        )

        assert "### Domain Business Logic Files" in result
        assert "src/models/user.py" in result
        assert "src/services/auth.py" in result

    def test_domain_business_logic_shows_rich_classes(self):
        """DOMAIN_BUSINESS_LOGIC shows classes with multiple methods."""
        from unfamiliar.analysis.models import FunctionDef

        parsed_files = {
            "src/user.py": ParsedFile(
                path="src/user.py",
                language="python",
                definitions=[
                    FunctionDef(
                        name="User",
                        line_start=1,
                        line_end=50,
                        is_async=False,
                        kind="class",
                    ),
                    FunctionDef(
                        name="__init__",
                        line_start=2,
                        line_end=10,
                        is_async=False,
                        kind="function",
                    ),
                    FunctionDef(
                        name="get_name",
                        line_start=12,
                        line_end=20,
                        is_async=False,
                        kind="function",
                    ),
                    FunctionDef(
                        name="set_name",
                        line_start=22,
                        line_end=30,
                        is_async=False,
                        kind="function",
                    ),
                    FunctionDef(
                        name="validate",
                        line_start=32,
                        line_end=40,
                        is_async=False,
                        kind="function",
                    ),
                ],
            ),
        }
        analysis = make_analysis_result(parsed_files=parsed_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DOMAIN_BUSINESS_LOGIC,
            previous_missions=[],
        )

        assert "### Rich Domain Classes" in result
        assert "src/user.py.User" in result
        assert "methods" in result

    def test_domain_business_logic_shows_entry_points(self):
        """DOMAIN_BUSINESS_LOGIC shows entry points as business workflows."""
        entry_points = [
            EntryPoint(
                file_path="src/api.py",
                entry_type=EntryType.API_ROUTE,
                description="User registration endpoint",
                line=42,
            ),
        ]
        analysis = make_analysis_result(entry_points=entry_points)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DOMAIN_BUSINESS_LOGIC,
            previous_missions=[],
        )

        assert "### Entry Points (Business Workflows)" in result
        assert "User registration endpoint" in result

    def test_domain_business_logic_shows_domain_modules(self):
        """DOMAIN_BUSINESS_LOGIC shows modules with domain hints."""
        modules = [
            DetectedModule(
                files=["src/domain/order.py"],
                primary_path="src/domain/order.py",
                file_count=1,
                confidence=0.9,
                category_hints=[InvestigationCategory.DOMAIN_BUSINESS_LOGIC],
            ),
        ]
        analysis = make_analysis_result(modules=modules)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.DOMAIN_BUSINESS_LOGIC,
            previous_missions=[],
        )

        assert "### Domain Modules (Business Logic)" in result
        assert "src/domain/order.py" in result


class TestBuildMissionContextPreviousMissions:
    """Tests for previous_missions parameter in build_mission_context()."""

    def test_with_previous_missions_lists_titles(self):
        """With previous_missions, output lists previous mission titles."""
        analysis = make_analysis_result()
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=["Mission A", "Mission B"],
        )

        assert "## Previously Generated Missions" in result
        assert "Mission A" in result
        assert "Mission B" in result

    def test_with_empty_previous_missions_no_section(self):
        """With empty previous_missions list, no previous missions section appears."""
        analysis = make_analysis_result()
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
        )

        assert "## Previously Generated Missions" not in result

    def test_previous_missions_includes_reference_note(self):
        """Previous missions section includes note about awareness-only reference."""
        analysis = make_analysis_result()
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=["Some Mission"],
        )

        assert "Reference for awareness only" in result
        assert "do NOT add as prerequisites" in result


class TestBuildMissionContextCategoryHints:
    """Tests for category hints filtering in build_mission_context()."""

    def test_modules_with_matching_category_hints_included(self):
        """Modules with category_hints matching current category are included
        in output.
        """
        modules = [
            DetectedModule(
                files=["src/auth.py"],
                primary_path="src/auth.py",
                file_count=1,
                confidence=0.9,
                category_hints=[InvestigationCategory.TESTING],
            ),
        ]
        analysis = make_analysis_result(modules=modules)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
        )

        assert "## Relevant Modules" in result
        assert "src/auth.py" in result

    def test_modules_without_matching_hints_still_produces_output(self):
        """Modules without matching category_hints still produce valid output."""
        modules = [
            DetectedModule(
                files=["src/core.py"],
                primary_path="src/core.py",
                file_count=1,
                confidence=0.9,
                category_hints=[InvestigationCategory.ARCHITECTURE],
            ),
        ]
        analysis = make_analysis_result(modules=modules)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
        )

        assert "## Files Relevant to Testing" in result
        assert "## Relevant Modules" in result


class TestBuildMissionContextTokenBudget:
    """Tests for token budget enforcement in build_mission_context()."""

    def test_token_budget_per_category_allocation(self):
        """Context stays within budget / 7 allocation per category."""
        analysis = make_analysis_result()
        briefing = make_briefing_result()

        token_budget = 7000  # Should result in ~1000 tokens per category
        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
            token_budget=token_budget,
        )

        estimated_tokens = len(result) // CHARS_PER_TOKEN
        per_category_budget = token_budget // 7

        # Allow some overhead for structure, but main content should be within budget
        assert estimated_tokens <= per_category_budget + 500

    def test_default_token_budget_produces_reasonable_output(self):
        """Default token budget produces non-empty output."""
        analysis = make_analysis_result()
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.ARCHITECTURE,
            previous_missions=[],
            token_budget=DEFAULT_TOKEN_BUDGET,
        )

        assert len(result) > 100
        assert "## Files Relevant to" in result


class TestBuildModuleDescriptions:
    """Tests for build_module_descriptions() function."""

    def test_with_three_modules_produces_indexed_list(self):
        """With 3 modules, output contains indexed list (0, 1, 2) with names."""
        modules = [
            ModuleDescription(
                name="Auth Module",
                description="Handles authentication",
                security_relevant=False,
            ),
            ModuleDescription(
                name="Database Module",
                description="Database operations",
                security_relevant=False,
            ),
            ModuleDescription(
                name="API Module",
                description="REST endpoints",
                security_relevant=False,
            ),
        ]
        briefing = make_briefing_result(modules=modules)

        result = build_module_descriptions(briefing)

        assert "## Module Index" in result
        assert "[0] **Auth Module**" in result
        assert "[1] **Database Module**" in result
        assert "[2] **API Module**" in result
        assert "Handles authentication" in result
        assert "Database operations" in result
        assert "REST endpoints" in result

    def test_with_empty_modules_returns_minimal_string(self):
        """With empty modules list, returns minimal string with header only."""
        briefing = make_briefing_result(modules=[])

        result = build_module_descriptions(briefing)

        assert "## Module Index" in result
        # Only the header line should be present
        lines = [line for line in result.split("\n") if line.strip()]
        assert len(lines) == 1

    def test_module_descriptions_include_security_relevant_flag(self):
        """Module descriptions include security_relevant flag when True."""
        modules = [
            ModuleDescription(
                name="Security Module",
                description="Handles secrets",
                security_relevant=True,
            ),
        ]
        briefing = make_briefing_result(modules=modules)

        result = build_module_descriptions(briefing)

        assert "*Security relevant*" in result

    def test_module_descriptions_without_security_flag(self):
        """Module descriptions without security_relevant flag do not show marker."""
        modules = [
            ModuleDescription(
                name="Utils Module",
                description="Helper functions",
                security_relevant=False,
            ),
        ]
        briefing = make_briefing_result(modules=modules)

        result = build_module_descriptions(briefing)

        assert "*Security relevant*" not in result

    def test_module_index_header_format(self):
        """Module index has correct header format with guidance text."""
        modules = [
            ModuleDescription(
                name="Test Module",
                description="Test description",
                security_relevant=False,
            ),
        ]
        briefing = make_briefing_result(modules=modules)

        result = build_module_descriptions(briefing)

        assert "## Module Index (use in module_index field)" in result


class TestBuildMissionContextIntegration:
    """Integration tests for build_mission_context() with realistic data."""

    def test_full_context_includes_all_sections(self):
        """Full context includes files, modules, category context, and
        previous missions.
        """
        modules = [
            DetectedModule(
                files=["src/auth.py", "src/auth_utils.py"],
                primary_path="src/auth.py",
                file_count=2,
                confidence=0.9,
                category_hints=[InvestigationCategory.TESTING],
            ),
        ]
        test_info = FileTestInfo(
            test_files={"tests/test_auth.py"},
            tier="basic",
        )
        analysis = make_analysis_result(
            modules=modules,
            test_info=test_info,
        )
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=["Previous Mission A"],
        )

        # Verify all expected sections are present
        assert "## Files Relevant to Testing" in result
        assert "## Relevant Modules" in result
        assert "## Testing Context" in result
        assert "## Previously Generated Missions" in result

    def test_scored_files_with_category_keywords_included(self):
        """Scored files with category-relevant keywords in path are included."""
        scored_files = [
            ScoredFile(path="src/test_helper.py", score=50, reasons=[]),
            ScoredFile(path="src/conftest.py", score=40, reasons=[]),
        ]
        analysis = make_analysis_result(scored_files=scored_files)
        briefing = make_briefing_result()

        result = build_mission_context(
            analysis=analysis,
            briefing_result=briefing,
            category=InvestigationCategory.TESTING,
            previous_missions=[],
        )

        # Files with 'test' keyword should be listed
        assert "src/test_helper.py" in result
        assert "src/conftest.py" in result
