"""Tests for project structure reporter module."""

import os
from pathlib import Path
from typing import Generator

import pytest

from mcp_server_neurolorap.project_structure_reporter import (
    ProjectStructureReporter,
)


@pytest.fixture
def temp_project(tmp_path: Path) -> Generator[Path, None, None]:
    """Create a temporary project structure for testing."""
    # Create some test files
    (tmp_path / "src").mkdir()
    (tmp_path / "src" / "main.py").write_text("def main():\n    pass\n")
    (tmp_path / "src" / "utils.py").write_text("x = 1\n" * 400)  # Large file
    (tmp_path / "README.md").write_text("# Test Project\n")
    (tmp_path / "binary.bin").write_bytes(b"\x00\x01\x02\x03")

    yield tmp_path


def test_should_ignore(temp_project: Path) -> None:
    """Test file/directory ignore patterns."""
    reporter = ProjectStructureReporter(
        root_dir=temp_project,
        ignore_patterns=["*.bin", "*.pyc"],
    )

    assert reporter.should_ignore(temp_project / "binary.bin")
    assert reporter.should_ignore(temp_project / "cache.pyc")
    assert not reporter.should_ignore(temp_project / "src" / "main.py")


def test_count_lines(temp_project: Path) -> None:
    """Test line counting functionality."""
    reporter = ProjectStructureReporter(root_dir=temp_project)

    assert reporter.count_lines(temp_project / "src" / "main.py") == 2
    assert reporter.count_lines(temp_project / "README.md") == 1
    assert reporter.count_lines(temp_project / "binary.bin") == 0


def test_analyze_file(temp_project: Path) -> None:
    """Test file analysis functionality."""
    reporter = ProjectStructureReporter(root_dir=temp_project)

    # Test normal file
    main_data = reporter.analyze_file(temp_project / "src" / "main.py")
    assert main_data["path"] == os.path.join("src", "main.py")
    assert main_data["lines"] == 2
    assert not main_data["is_large"]
    assert not main_data["is_complex"]
    assert not main_data["error"]

    # Test large file
    utils_data = reporter.analyze_file(temp_project / "src" / "utils.py")
    assert utils_data["path"] == os.path.join("src", "utils.py")
    assert utils_data["lines"] == 400
    assert not utils_data["is_large"]  # Not large by size
    assert utils_data["is_complex"]  # Large by lines
    assert not utils_data["error"]

    # Test binary file
    binary_data = reporter.analyze_file(temp_project / "binary.bin")
    assert binary_data["path"] == "binary.bin"
    assert binary_data["lines"] == 0
    assert not binary_data["is_large"]
    assert not binary_data["is_complex"]
    assert not binary_data["error"]


def test_analyze_project_structure(temp_project: Path) -> None:
    """Test project structure analysis."""
    reporter = ProjectStructureReporter(
        root_dir=temp_project,
        ignore_patterns=["*.bin"],
    )

    report_data = reporter.analyze_project_structure()

    assert len(report_data["files"]) == 3  # main.py, utils.py, README.md
    assert report_data["total_lines"] > 0
    assert report_data["total_tokens"] > 0
    assert report_data["large_files"] == 0
    assert report_data["error_files"] == 0


def test_generate_markdown_report(temp_project: Path) -> None:
    """Test markdown report generation."""
    reporter = ProjectStructureReporter(root_dir=temp_project)
    report_data = reporter.analyze_project_structure()

    output_path = temp_project / "report.md"
    reporter.generate_markdown_report(report_data, output_path)

    assert output_path.exists()
    content = output_path.read_text()
    assert "# Project Structure Report" in content
    assert "## Project Tree" in content
    assert "## Summary" in content
    assert "## Notes" in content
