"""
Tests for the CodebaseIndexer.
"""

from __future__ import annotations

from pathlib import Path

import pytest

from hallucination_grep.indexer import CodebaseIndexer


class TestCodebaseIndexer:
    def test_indexes_functions(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert "get_user_data" in idx.functions
        assert "format_response" in idx.functions
        assert "parse_input" in idx.functions
        assert "run" in idx.functions

    def test_indexes_classes(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert "UserManager" in idx.classes
        assert "BaseModel" in idx.classes

    def test_indexes_methods(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert "save" in idx.methods
        assert "load" in idx.methods
        assert "delete" in idx.methods
        assert "get_user_by_id" in idx.methods

    def test_indexes_variables(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert "DB_URL" in idx.variables
        assert "SECRET_KEY" in idx.variables

    def test_indexes_files(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert any("users.py" in f for f in idx.files)
        assert any("settings.py" in f for f in idx.files)
        assert any("format.py" in f for f in idx.files)

    def test_counts_python_files(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert idx.python_files_count >= 5  # users, base, format, settings, main

    def test_function_location(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        fdefs = idx.functions["get_user_data"]
        assert len(fdefs) >= 1
        assert "users.py" in fdefs[0].file
        assert fdefs[0].line > 0

    def test_class_location(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        cdefs = idx.classes["UserManager"]
        assert "users.py" in cdefs[0].file
        assert "get_user_by_id" in cdefs[0].methods

    def test_skips_pycache(self, tmp_codebase: Path) -> None:
        pycache = tmp_codebase / "__pycache__"
        pycache.mkdir()
        (pycache / "junk.pyc").write_bytes(b"\x00\x01")
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert not any("__pycache__" in f for f in idx.files)

    def test_handles_syntax_error_gracefully(self, tmp_codebase: Path) -> None:
        bad = tmp_codebase / "broken.py"
        bad.write_text("def foo(:\n    pass\n", encoding="utf-8")
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        assert len(idx.parse_errors) >= 1
        assert any("broken.py" in e for e in idx.parse_errors)

    def test_module_exports(self, tmp_codebase: Path) -> None:
        idx = CodebaseIndexer(str(tmp_codebase)).build()
        # src/users module should export UserManager and get_user_data
        # Module names use dotted notation (matching Python import style)
        users_module = "src.users"
        assert users_module in idx.module_exports
        assert "UserManager" in idx.module_exports[users_module]
        assert "get_user_data" in idx.module_exports[users_module]
