#!/usr/bin/env python3
"""
Tests for api_reference_builder.py - Markdown API documentation generation.

Test Coverage:
- Class formatting
- Function formatting
- Parameter table generation
- Markdown output structure
- Integration with code analysis results
"""

import os
import shutil
import sys
import tempfile
import unittest
from pathlib import Path

# Add src to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))

from skill_seekers.cli.api_reference_builder import APIReferenceBuilder


class TestAPIReferenceBuilder(unittest.TestCase):
    """Tests for API reference builder"""

    def setUp(self):
        """Set up test environment"""
        self.temp_dir = tempfile.mkdtemp()
        self.output_dir = Path(self.temp_dir) / "api_reference"

    def tearDown(self):
        """Clean up test environment"""
        shutil.rmtree(self.temp_dir, ignore_errors=True)

    def test_class_formatting(self):
        """Test markdown formatting for class signatures."""
        code_analysis = {
            "files": [
                {
                    "file": "test.py",
                    "language": "Python",
                    "classes": [
                        {
                            "name": "Calculator",
                            "docstring": "A simple calculator class.",
                            "base_classes": ["object"],
                            "methods": [
                                {
                                    "name": "add",
                                    "parameters": [
                                        {"name": "a", "type_hint": "int", "default": None},
                                        {"name": "b", "type_hint": "int", "default": None},
                                    ],
                                    "return_type": "int",
                                    "docstring": "Add two numbers.",
                                    "is_async": False,
                                    "is_method": True,
                                    "decorators": [],
                                }
                            ],
                        }
                    ],
                    "functions": [],
                }
            ]
        }

        builder = APIReferenceBuilder(code_analysis)
        generated = builder.build_reference(self.output_dir)

        # Verify file was generated
        self.assertEqual(len(generated), 1)
        output_file = list(generated.values())[0]
        self.assertTrue(output_file.exists())

        # Verify content
        content = output_file.read_text()
        self.assertIn("### Calculator", content)
        self.assertIn("A simple calculator class", content)
        self.assertIn("**Inherits from**: object", content)
        self.assertIn("##### add", content)
        self.assertIn("Add two numbers", content)

    def test_function_formatting(self):
        """Test markdown formatting for function signatures."""
        code_analysis = {
            "files": [
                {
                    "file": "utils.py",
                    "language": "Python",
                    "classes": [],
                    "functions": [
                        {
                            "name": "calculate_sum",
                            "parameters": [
                                {"name": "numbers", "type_hint": "list", "default": None}
                            ],
                            "return_type": "int",
                            "docstring": "Calculate sum of numbers.",
                            "is_async": False,
                            "is_method": False,
                            "decorators": [],
                        }
                    ],
                }
            ]
        }

        builder = APIReferenceBuilder(code_analysis)
        generated = builder.build_reference(self.output_dir)

        # Verify content
        output_file = list(generated.values())[0]
        content = output_file.read_text()

        self.assertIn("## Functions", content)
        self.assertIn("### calculate_sum", content)
        self.assertIn("Calculate sum of numbers", content)
        self.assertIn("**Returns**: `int`", content)

    def test_parameter_table_generation(self):
        """Test parameter table formatting."""
        code_analysis = {
            "files": [
                {
                    "file": "test.py",
                    "language": "Python",
                    "classes": [],
                    "functions": [
                        {
                            "name": "create_user",
                            "parameters": [
                                {"name": "name", "type_hint": "str", "default": None},
                                {"name": "age", "type_hint": "int", "default": "18"},
                                {"name": "active", "type_hint": "bool", "default": "True"},
                            ],
                            "return_type": "dict",
                            "docstring": "Create a user object.",
                            "is_async": False,
                            "is_method": False,
                            "decorators": [],
                        }
                    ],
                }
            ]
        }

        builder = APIReferenceBuilder(code_analysis)
        generated = builder.build_reference(self.output_dir)

        # Verify parameter table
        output_file = list(generated.values())[0]
        content = output_file.read_text()

        self.assertIn("**Parameters**:", content)
        self.assertIn("| Name | Type | Default | Description |", content)
        self.assertIn("| name | str | - |", content)  # Parameters with no default show "-"
        self.assertIn("| age | int | 18 |", content)
        self.assertIn("| active | bool | True |", content)

    def test_markdown_output_structure(self):
        """Test overall markdown document structure."""
        code_analysis = {
            "files": [
                {
                    "file": "module.py",
                    "language": "Python",
                    "classes": [
                        {
                            "name": "TestClass",
                            "docstring": "Test class.",
                            "base_classes": [],
                            "methods": [],
                        }
                    ],
                    "functions": [
                        {
                            "name": "test_func",
                            "parameters": [],
                            "return_type": None,
                            "docstring": "Test function.",
                            "is_async": False,
                            "is_method": False,
                            "decorators": [],
                        }
                    ],
                }
            ]
        }

        builder = APIReferenceBuilder(code_analysis)
        generated = builder.build_reference(self.output_dir)

        # Verify structure
        output_file = list(generated.values())[0]
        content = output_file.read_text()

        # Check header
        self.assertIn("# API Reference: module.py", content)
        self.assertIn("**Language**: Python", content)
        self.assertIn("**Source**: `module.py`", content)

        # Check sections in order
        classes_pos = content.find("## Classes")
        functions_pos = content.find("## Functions")

        self.assertNotEqual(classes_pos, -1)
        self.assertNotEqual(functions_pos, -1)
        self.assertLess(classes_pos, functions_pos)

    def test_integration_with_code_analyzer(self):
        """Test integration with actual code analyzer output format."""
        # Simulate real code analyzer output
        code_analysis = {
            "files": [
                {
                    "file": "calculator.py",
                    "language": "Python",
                    "classes": [
                        {
                            "name": "Calculator",
                            "base_classes": [],
                            "methods": [
                                {
                                    "name": "add",
                                    "parameters": [
                                        {"name": "a", "type_hint": "float", "default": None},
                                        {"name": "b", "type_hint": "float", "default": None},
                                    ],
                                    "return_type": "float",
                                    "docstring": "Add two numbers.",
                                    "decorators": [],
                                    "is_async": False,
                                    "is_method": True,
                                }
                            ],
                            "docstring": "Calculator class.",
                            "line_number": 1,
                        }
                    ],
                    "functions": [],
                },
                {
                    "file": "utils.js",
                    "language": "JavaScript",
                    "classes": [],
                    "functions": [
                        {
                            "name": "formatDate",
                            "parameters": [{"name": "date", "type_hint": None, "default": None}],
                            "return_type": None,
                            "docstring": None,
                            "is_async": False,
                            "is_method": False,
                            "decorators": [],
                        }
                    ],
                },
            ]
        }

        builder = APIReferenceBuilder(code_analysis)
        generated = builder.build_reference(self.output_dir)

        # Verify multiple files generated
        self.assertEqual(len(generated), 2)

        # Verify filenames
        filenames = [f.name for f in generated.values()]
        self.assertIn("calculator.md", filenames)
        self.assertIn("utils.md", filenames)

        # Verify Python file content
        py_file = next(f for f in generated.values() if f.name == "calculator.md")
        py_content = py_file.read_text()
        self.assertIn("Calculator class", py_content)
        self.assertIn("add(a: float, b: float) → float", py_content)

        # Verify JavaScript file content
        js_file = next(f for f in generated.values() if f.name == "utils.md")
        js_content = js_file.read_text()
        self.assertIn("formatDate", js_content)
        self.assertIn("**Language**: JavaScript", js_content)

    def test_async_function_indicator(self):
        """Test that async functions are marked in output."""
        code_analysis = {
            "files": [
                {
                    "file": "async_utils.py",
                    "language": "Python",
                    "classes": [],
                    "functions": [
                        {
                            "name": "fetch_data",
                            "parameters": [{"name": "url", "type_hint": "str", "default": None}],
                            "return_type": "dict",
                            "docstring": "Fetch data from URL.",
                            "is_async": True,
                            "is_method": False,
                            "decorators": [],
                        }
                    ],
                }
            ]
        }

        builder = APIReferenceBuilder(code_analysis)
        generated = builder.build_reference(self.output_dir)

        # Verify async indicator
        output_file = list(generated.values())[0]
        content = output_file.read_text()

        self.assertIn("**Async function**", content)
        self.assertIn("fetch_data", content)

    def test_empty_analysis_skipped(self):
        """Test that files with no analysis are skipped."""
        code_analysis = {
            "files": [
                {"file": "empty.py", "language": "Python", "classes": [], "functions": []},
                {
                    "file": "valid.py",
                    "language": "Python",
                    "classes": [],
                    "functions": [
                        {
                            "name": "test",
                            "parameters": [],
                            "return_type": None,
                            "docstring": None,
                            "is_async": False,
                            "is_method": False,
                            "decorators": [],
                        }
                    ],
                },
            ]
        }

        builder = APIReferenceBuilder(code_analysis)
        generated = builder.build_reference(self.output_dir)

        # Only valid.py should be generated
        self.assertEqual(len(generated), 1)
        self.assertIn("valid.py", list(generated.keys())[0])


if __name__ == "__main__":
    # Run tests with verbose output
    unittest.main(verbosity=2)
