"""Tests for CodebaseScanner."""

import os
import tempfile
import pytest
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from claudemd.generators.codebase_scanner import CodebaseScanner


@pytest.fixture
def project():
    """Create a temp project with some files."""
    with tempfile.TemporaryDirectory() as tmpdir:
        # Create structure
        os.makedirs(os.path.join(tmpdir, "src"))
        os.makedirs(os.path.join(tmpdir, "tests"))
        os.makedirs(os.path.join(tmpdir, "docs"))
        os.makedirs(os.path.join(tmpdir, "node_modules", "some-pkg"))  # Should be skipped

        # Python files
        with open(os.path.join(tmpdir, "main.py"), "w") as f:
            f.write("# Main entry point\n")
        with open(os.path.join(tmpdir, "src", "app.py"), "w") as f:
            f.write("# App\n")
        with open(os.path.join(tmpdir, "tests", "test_main.py"), "w") as f:
            f.write("# Tests\n")

        # Config files
        with open(os.path.join(tmpdir, "README.md"), "w") as f:
            f.write("# My Project\n")
        with open(os.path.join(tmpdir, "pyproject.toml"), "w") as f:
            f.write("[project]\nname = 'myapp'\n")

        yield tmpdir


class TestCodebaseScanner:
    def test_scan_returns_dict(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        assert isinstance(result, dict)
        assert "tree" in result
        assert "stats" in result
        assert "key_files" in result

    def test_project_name(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        # Should be the temp dir basename
        assert result["project_name"] == os.path.basename(project)

    def test_finds_key_files(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        key_files = result["key_files"]
        assert any("main.py" in f for f in key_files)

    def test_counts_python_files(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        stats = result["stats"]
        assert stats["total_code_files"] >= 3  # main.py, src/app.py, tests/test_main.py

    def test_python_extension_counted(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        by_ext = result["stats"]["by_extension"]
        assert ".py" in by_ext
        assert by_ext[".py"] >= 3

    def test_skips_node_modules(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        tree = result["tree"]
        assert "node_modules" not in tree

    def test_has_tests_detected(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        assert result["has_tests"] is True

    def test_has_docs_detected(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        assert result["has_docs"] is True

    def test_config_files_found(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        assert "pyproject.toml" in result["config_files"]
        assert "README.md" in result["config_files"]

    def test_top_level_dirs(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        dirs = result["top_level_dirs"]
        assert "src" in dirs
        assert "tests" in dirs
        assert "docs" in dirs
        assert "node_modules" not in dirs

    def test_tree_is_string(self, project):
        scanner = CodebaseScanner(project)
        result = scanner.scan()
        assert isinstance(result["tree"], str)
        assert len(result["tree"]) > 0

    def test_to_summary(self, project):
        scanner = CodebaseScanner(project)
        summary = scanner.to_summary()
        assert isinstance(summary, str)
        assert "Project:" in summary


class TestScannerSkipping:
    def test_skips_pycache(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            os.makedirs(os.path.join(tmpdir, "__pycache__"))
            with open(os.path.join(tmpdir, "__pycache__", "module.pyc"), "w") as f:
                f.write("")
            scanner = CodebaseScanner(tmpdir)
            result = scanner.scan()
            assert "__pycache__" not in result["tree"]

    def test_skips_venv(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            os.makedirs(os.path.join(tmpdir, ".venv", "lib"))
            scanner = CodebaseScanner(tmpdir)
            result = scanner.scan()
            assert ".venv" not in result["tree"]

    def test_skips_git(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            os.makedirs(os.path.join(tmpdir, ".git", "objects"))
            scanner = CodebaseScanner(tmpdir)
            result = scanner.scan()
            assert ".git" not in result["tree"]
