"""
Tests for FEATURE-026: Homepage Infinity Loop

Tests cover:
- Homepage service: Template rendering, stage mapping configuration
- Homepage API endpoint (if implemented)
- Template content validation

Note: Frontend JS behavior is validated via acceptance tests (browser-based).
      These tests focus on backend/configuration aspects.
"""
import pytest
from unittest.mock import Mock, patch


class TestHomepageStageMapping:
    """Unit tests for stage-to-sidebar mapping configuration"""

    def test_stage_mapping_has_eight_stages(self, homepage_service):
        """AC-2.1: Infinity loop displays 8 stage buttons"""
        mapping = homepage_service.get_stage_mapping()
        
        assert len(mapping) == 8
        expected_stages = [
            'ideation', 'requirement', 'implementation', 'deployment',
            'validation', 'monitoring', 'feedback', 'planning'
        ]
        for stage in expected_stages:
            assert stage in mapping

    def test_stage_mapping_control_stages_correct(self, homepage_service):
        """AC-2.2: Control loop has 4 stages (ideation, requirement, implementation, deployment)"""
        mapping = homepage_service.get_stage_mapping()
        
        control_stages = ['ideation', 'requirement', 'implementation', 'deployment']
        for stage in control_stages:
            assert mapping[stage]['theme'] == 'control'

    def test_stage_mapping_transparency_stages_correct(self, homepage_service):
        """AC-2.3: Transparency loop has 4 stages (validation, monitoring, feedback, planning)"""
        mapping = homepage_service.get_stage_mapping()
        
        transparency_stages = ['validation', 'monitoring', 'feedback', 'planning']
        for stage in transparency_stages:
            assert mapping[stage]['theme'] == 'transparency'

    def test_stage_mapping_deployment_is_tbd(self, homepage_service):
        """AC-3.6: Deployment stage shows TBD status"""
        mapping = homepage_service.get_stage_mapping()
        
        assert mapping['deployment']['status'] == 'tbd'

    def test_stage_mapping_ready_stages_have_selectors(self, homepage_service):
        """AC-4.1: Ready stages have valid sidebar selectors"""
        mapping = homepage_service.get_stage_mapping()
        
        ready_stages = [s for s, m in mapping.items() if m['status'] == 'ready']
        for stage in ready_stages:
            assert mapping[stage]['selector'] is not None
            assert len(mapping[stage]['selector']) > 0

    def test_ideation_maps_to_workplace(self, homepage_service):
        """AC-4.1: Ideation maps to Workplace → Ideation"""
        mapping = homepage_service.get_stage_mapping()
        
        assert mapping['ideation']['section'] == 'workplace'
        assert 'ideas' in mapping['ideation']['selector']

    def test_validation_maps_to_quality(self, homepage_service):
        """AC-4.1: Validation maps to Quality → Project Quality Report"""
        mapping = homepage_service.get_stage_mapping()
        
        assert mapping['validation']['section'] == 'quality'


class TestHomepageTemplate:
    """Unit tests for homepage HTML template generation"""

    def test_get_template_returns_html_string(self, homepage_service):
        """Template generation returns valid HTML"""
        template = homepage_service.get_template()
        
        assert isinstance(template, str)
        assert 'homepage-infinity-container' in template

    def test_template_contains_header(self, homepage_service):
        """Template includes X-IPE header"""
        template = homepage_service.get_template()
        
        assert 'X-IPE' in template

    def test_template_contains_all_stage_buttons(self, homepage_service):
        """AC-3.1: Template contains 8 stage buttons"""
        template = homepage_service.get_template()
        
        stages = ['ideation', 'requirement', 'implementation', 'deployment',
                  'validation', 'monitoring', 'feedback', 'planning']
        for stage in stages:
            assert f'data-stage="{stage}"' in template

    def test_template_contains_stage_icons(self, homepage_service):
        """AC-3.2: Stage buttons have emoji icons"""
        template = homepage_service.get_template()
        
        # At least some icons should be present
        icons = ['💡', '📋', '⚙️', '🚀', '✅', '📊', '💬', '📅']
        found_icons = sum(1 for icon in icons if icon in template)
        assert found_icons == 8

    def test_template_contains_loop_labels(self, homepage_service):
        """AC-2.2, AC-2.3: Template has CONTROL and TRANSPARENCY labels"""
        template = homepage_service.get_template()
        
        assert 'CONTROL' in template
        assert 'TRANSPARENCY' in template

    def test_template_contains_tbd_badge_for_deployment(self, homepage_service):
        """AC-3.6: Deployment button has TBD indicator"""
        template = homepage_service.get_template()
        
        # Find deployment section and check for TBD marker
        assert 'tbd' in template.lower() or 'coming soon' in template.lower()


class TestHomepageDataSelectorEscaping:
    """TASK-739: data-selector attribute values must be properly HTML-escaped"""

    def test_data_selector_quotes_escaped_in_template(self, homepage_service):
        """data-selector values with quotes must use &quot; to prevent broken HTML attributes"""
        template = homepage_service.get_template()
        
        # Selectors contain double quotes like [data-path="x-ipe-docs/ideas"]
        # These MUST be escaped as &quot; inside data-selector="..." attribute
        # Unescaped quotes break HTML parsing and SVG foreignObject screenshot capture
        import re
        # Find all data-selector attribute values
        matches = re.findall(r'data-selector="([^"]*)"', template)
        
        for value in matches:
            # Each matched value should NOT contain raw double quotes
            # (if it did, the regex wouldn't have matched the full value)
            assert '"' not in value, (
                f"data-selector contains unescaped double quote: {value}"
            )
        
        # Verify that selectors with quotes are present (escaped as &quot;)
        assert '&quot;' in template or all(
            m.get('selector') is None 
            for m in homepage_service.get_stage_mapping().values()
        ), "Selectors with quotes should be escaped as &quot;"

    def test_data_selector_values_preserve_selector_content(self, homepage_service):
        """Escaped data-selector values should be decodable to original selectors"""
        from html import unescape
        template = homepage_service.get_template()
        
        import re
        matches = re.findall(r'data-selector="([^"]*)"', template)
        
        mapping = homepage_service.get_stage_mapping()
        expected_selectors = [m['selector'] for m in mapping.values() if m['selector']]
        
        # Each escaped value, when unescaped, should match an expected selector
        decoded_values = [unescape(v) for v in matches if v]
        for expected in expected_selectors:
            assert expected in decoded_values, (
                f"Selector {expected} not found in template data-selector values"
            )


class TestHomepageAPI:
    """API endpoint tests for homepage (skipped - no Flask app in this project)"""

    @pytest.mark.skip(reason="No Flask app in this project, API tests via acceptance")
    def test_homepage_endpoint_returns_template(self):
        """GET /api/homepage returns HTML template"""
        pass

    @pytest.mark.skip(reason="No Flask app in this project, API tests via acceptance")
    def test_homepage_stage_mapping_endpoint(self):
        """GET /api/homepage/stages returns stage mapping JSON"""
        pass


class TestHomepageStageDetails:
    """Detailed tests for each stage configuration"""

    def test_ideation_stage_config(self, homepage_service):
        """Ideation stage has correct configuration"""
        mapping = homepage_service.get_stage_mapping()
        ideation = mapping['ideation']
        
        assert ideation['icon'] == '💡'
        assert ideation['label'] == 'IDEATION'
        assert ideation['theme'] == 'control'
        assert ideation['status'] == 'ready'
        assert ideation['section'] == 'workplace'

    def test_requirement_stage_config(self, homepage_service):
        """Requirement stage has correct configuration"""
        mapping = homepage_service.get_stage_mapping()
        req = mapping['requirement']
        
        assert req['icon'] == '📋'
        assert req['label'] == 'REQUIREMENT'
        assert req['theme'] == 'control'
        assert req['status'] == 'ready'
        assert req['section'] == 'project'

    def test_implementation_stage_config(self, homepage_service):
        """Implementation stage has correct configuration"""
        mapping = homepage_service.get_stage_mapping()
        impl = mapping['implementation']
        
        assert impl['icon'] == '⚙️'
        assert impl['label'] in ['IMPLEMENT', 'IMPLEMENTATION']
        assert impl['theme'] == 'control'
        assert impl['status'] == 'ready'

    def test_deployment_stage_config(self, homepage_service):
        """Deployment stage has TBD status"""
        mapping = homepage_service.get_stage_mapping()
        deploy = mapping['deployment']
        
        assert deploy['icon'] == '🚀'
        assert deploy['status'] == 'tbd'
        assert deploy['theme'] == 'control'

    def test_validation_stage_config(self, homepage_service):
        """Validation stage has correct configuration"""
        mapping = homepage_service.get_stage_mapping()
        val = mapping['validation']
        
        assert val['icon'] == '✅'
        assert val['theme'] == 'transparency'
        assert val['status'] == 'ready'
        assert val['section'] == 'quality'

    def test_monitoring_stage_config(self, homepage_service):
        """Monitoring stage has correct configuration"""
        mapping = homepage_service.get_stage_mapping()
        mon = mapping['monitoring']
        
        assert mon['icon'] == '📊'
        assert mon['theme'] == 'transparency'
        assert mon['status'] == 'ready'

    def test_feedback_stage_config(self, homepage_service):
        """Feedback stage has correct configuration"""
        mapping = homepage_service.get_stage_mapping()
        fb = mapping['feedback']
        
        assert fb['icon'] == '💬'
        assert fb['theme'] == 'transparency'
        assert fb['status'] == 'ready'
        assert fb['section'] == 'feedback'

    def test_planning_stage_config(self, homepage_service):
        """Planning stage has correct configuration"""
        mapping = homepage_service.get_stage_mapping()
        plan = mapping['planning']
        
        assert plan['icon'] == '📅'
        assert plan['theme'] == 'transparency'
        assert plan['status'] == 'ready'
        assert plan['section'] == 'management'


class TestHomepageButtonPositions:
    """Tests for button positioning on infinity loop"""

    def test_all_stages_have_positions(self, homepage_service):
        """Each stage has left and top position defined"""
        mapping = homepage_service.get_stage_mapping()
        
        for stage, config in mapping.items():
            assert 'position' in config, f"Stage {stage} missing position"
            assert 'left' in config['position'], f"Stage {stage} missing left position"
            assert 'top' in config['position'], f"Stage {stage} missing top position"

    def test_control_stages_on_left_side(self, homepage_service):
        """Control stages positioned on left half of loop (left < 60%)"""
        mapping = homepage_service.get_stage_mapping()
        
        control_stages = ['ideation', 'requirement', 'implementation', 'deployment']
        for stage in control_stages:
            left_pct = float(mapping[stage]['position']['left'].replace('%', ''))
            # Most control stages should be on left side (deployment crosses to middle)
            assert left_pct < 70, f"Stage {stage} too far right: {left_pct}%"

    def test_transparency_stages_on_right_side(self, homepage_service):
        """Transparency stages positioned on right half of loop (left > 35%)"""
        mapping = homepage_service.get_stage_mapping()
        
        transparency_stages = ['validation', 'monitoring', 'feedback', 'planning']
        for stage in transparency_stages:
            left_pct = float(mapping[stage]['position']['left'].replace('%', ''))
            # Most transparency stages should be on right side (planning crosses to middle)
            assert left_pct > 30, f"Stage {stage} too far left: {left_pct}%"


class TestHomepageTracing:
    """Tracing tests for FEATURE-026"""

    def test_homepage_service_has_tracing_decorator(self, homepage_service):
        """HomepageService methods should have @x_ipe_tracing decorator"""
        from x_ipe.services.homepage_service import HomepageService
        
        # Check that the methods are wrapped (decorator applied)
        get_template_method = HomepageService.get_template
        get_mapping_method = HomepageService.get_stage_mapping
        
        # Decorated functions have __wrapped__ attribute
        assert hasattr(get_template_method, '__wrapped__') or callable(get_template_method)
        assert hasattr(get_mapping_method, '__wrapped__') or callable(get_mapping_method)

    def test_homepage_service_tracing_invocation(self, homepage_service):
        """Service methods can be called successfully with tracing"""
        # Just verify the tracing decorator doesn't break functionality
        mapping = homepage_service.get_stage_mapping()
        template = homepage_service.get_template()
        
        assert len(mapping) == 8
        assert 'homepage-infinity-container' in template


# ============================================================================
# Fixtures
# ============================================================================

@pytest.fixture
def homepage_service():
    """Create HomepageService instance"""
    from x_ipe.services.homepage_service import HomepageService
    return HomepageService()
