"""
Unit tests for MCP Model Discovery Tool

Tests the .sim file parser and FEA model discovery functionality.
"""

import pytest
from pathlib import Path
import sys

# Add project root to path
project_root = Path(__file__).parent.parent.parent.parent
sys.path.insert(0, str(project_root))

from mcp_server.tools.model_discovery import (
    discover_fea_model,
    format_discovery_result_for_llm,
    SimFileParser
)


class TestSimFileParser:
    """Test the SimFileParser class"""

    @pytest.fixture
    def example_sim_path(self):
        """Path to example .sim file"""
        return project_root / "examples" / "test_bracket.sim"

    def test_parser_initialization(self, example_sim_path):
        """Test that parser initializes correctly"""
        parser = SimFileParser(example_sim_path)
        assert parser.sim_path.exists()
        assert parser.tree is not None
        assert parser.root is not None

    def test_parser_file_not_found(self):
        """Test error handling for missing file"""
        with pytest.raises(FileNotFoundError):
            SimFileParser("/nonexistent/path/file.sim")

    def test_parser_invalid_extension(self):
        """Test error handling for non-.sim file"""
        with pytest.raises(ValueError):
            SimFileParser(project_root / "README.md")

    def test_extract_solutions(self, example_sim_path):
        """Test solution extraction"""
        parser = SimFileParser(example_sim_path)
        solutions = parser.extract_solutions()

        assert len(solutions) > 0
        assert solutions[0]['name'] == 'Structural Analysis 1'
        assert solutions[0]['type'] == 'Static Structural'
        assert solutions[0]['solver'] == 'NX Nastran'

    def test_extract_expressions(self, example_sim_path):
        """Test expression extraction"""
        parser = SimFileParser(example_sim_path)
        expressions = parser.extract_expressions()

        assert len(expressions) > 0

        # Check for expected expressions
        expr_names = [e['name'] for e in expressions]
        assert 'wall_thickness' in expr_names
        assert 'hole_diameter' in expr_names
        assert 'rib_spacing' in expr_names

        # Check expression values
        wall_thickness = next(e for e in expressions if e['name'] == 'wall_thickness')
        assert wall_thickness['value'] == '5.0'
        assert wall_thickness['units'] == 'mm'

    def test_extract_fem_info(self, example_sim_path):
        """Test FEM information extraction"""
        parser = SimFileParser(example_sim_path)
        fem_info = parser.extract_fem_info()

        # Check mesh info
        assert 'mesh' in fem_info
        assert fem_info['mesh']['name'] == 'Bracket Mesh'
        assert fem_info['mesh']['node_count'] == '8234'
        assert fem_info['mesh']['element_count'] == '4521'

        # Check materials
        assert len(fem_info['materials']) > 0
        assert fem_info['materials'][0]['name'] == 'Aluminum 6061-T6'

        # Check loads
        assert len(fem_info['loads']) > 0
        assert fem_info['loads'][0]['name'] == 'Applied Force'

        # Check constraints
        assert len(fem_info['constraints']) > 0
        assert fem_info['constraints'][0]['name'] == 'Fixed Support'


class TestDiscoverFEAModel:
    """Test the main discover_fea_model function"""

    @pytest.fixture
    def example_sim_path(self):
        """Path to example .sim file"""
        return str(project_root / "examples" / "test_bracket.sim")

    def test_successful_discovery(self, example_sim_path):
        """Test successful model discovery"""
        result = discover_fea_model(example_sim_path)

        assert result['status'] == 'success'
        assert result['file_exists'] is True
        assert 'solutions' in result
        assert 'expressions' in result
        assert 'fem_info' in result
        assert 'summary' in result

        # Check summary statistics
        assert result['summary']['solution_count'] >= 1
        assert result['summary']['expression_count'] >= 3

    def test_file_not_found_error(self):
        """Test error handling for missing file"""
        result = discover_fea_model("/nonexistent/file.sim")

        assert result['status'] == 'error'
        assert result['error_type'] == 'file_not_found'
        assert 'message' in result
        assert 'suggestion' in result

    def test_result_structure(self, example_sim_path):
        """Test that result has expected structure"""
        result = discover_fea_model(example_sim_path)

        # Check top-level keys
        expected_keys = ['status', 'sim_file', 'file_exists', 'solutions',
                        'expressions', 'fem_info', 'linked_files', 'metadata', 'summary']

        for key in expected_keys:
            assert key in result, f"Missing key: {key}"

        # Check summary keys
        expected_summary_keys = ['solution_count', 'expression_count',
                                'material_count', 'load_count', 'constraint_count']

        for key in expected_summary_keys:
            assert key in result['summary'], f"Missing summary key: {key}"


class TestFormatDiscoveryResult:
    """Test the Markdown formatting function"""

    @pytest.fixture
    def example_sim_path(self):
        """Path to example .sim file"""
        return str(project_root / "examples" / "test_bracket.sim")

    def test_format_success_result(self, example_sim_path):
        """Test formatting of successful discovery"""
        result = discover_fea_model(example_sim_path)
        formatted = format_discovery_result_for_llm(result)

        assert isinstance(formatted, str)
        assert '# FEA Model Analysis' in formatted
        assert 'Solutions' in formatted
        assert 'Expressions' in formatted
        assert 'wall_thickness' in formatted

    def test_format_error_result(self):
        """Test formatting of error result"""
        result = discover_fea_model("/nonexistent/file.sim")
        formatted = format_discovery_result_for_llm(result)

        assert isinstance(formatted, str)
        assert '❌' in formatted or 'Error' in formatted
        assert result['message'] in formatted


# Integration test
def test_end_to_end_workflow():
    """
    Test the complete workflow:
    1. Discover model
    2. Format for LLM
    3. Verify output is useful
    """
    example_sim = str(project_root / "examples" / "test_bracket.sim")

    # Step 1: Discover
    result = discover_fea_model(example_sim)
    assert result['status'] == 'success'

    # Step 2: Format
    formatted = format_discovery_result_for_llm(result)
    assert len(formatted) > 100  # Should be substantial output

    # Step 3: Verify key information is present
    assert 'wall_thickness' in formatted
    assert 'Aluminum' in formatted
    assert 'Static Structural' in formatted

    print("\n" + "="*60)
    print("INTEGRATION TEST OUTPUT:")
    print("="*60)
    print(formatted)
    print("="*60)


if __name__ == "__main__":
    # Run tests with pytest
    pytest.main([__file__, "-v", "-s"])
