"""
pytest tests for status_formatter.py - AIVA Voice Command Bridge Status Report Formatter
Target: >90% coverage with unit, integration, and edge case tests
"""

import pytest
import json
from unittest.mock import patch, MagicMock
from typing import Dict, Any, Optional


# ============================================================================
# FIXTURES
# ============================================================================

@pytest.fixture
def formatter():
    """Import and return the formatter instance."""
    from status_formatter import StatusFormatter
    return StatusFormatter()


@pytest.fixture
def progress_status():
    """Sample progress status data."""
    return {
        'status': 'running',
        'task': 'building_api',
        'progress': 65,
        'eta_minutes': 12
    }


@pytest.fixture
def queue_status():
    """Sample queue status data."""
    return {
        'pending_directives': 3,
        'completed_today': 15,
        'failed': 1
    }


@pytest.fixture
def error_status():
    """Sample error status data."""
    return {
        'error': 'database_connection_failed',
        'retry_in': 30
    }


@pytest.fixture
def completion_status():
    """Sample completion status data."""
    return {
        'status': 'completed',
        'task': 'data_migration',
        'duration_minutes': 45,
        'items_processed': 1250
    }


@pytest.fixture
def system_health_status():
    """Sample system health status data."""
    return {
        'cpu_usage': 78,
        'memory_usage': 62,
        'disk_usage': 45,
        'active_connections': 12
    }


@pytest.fixture
def empty_status():
    """Empty status data for edge case testing."""
    return {}


@pytest.fixture
def malformed_status():
    """Malformed status data with invalid types."""
    return {
        'status': 'running',
        'progress': 'sixty-five',  # Should be int
        'eta_minutes': 'twelve'    # Should be int
    }


# ============================================================================
# UNIT TESTS - Progress Status Formatting
# ============================================================================

class TestProgressStatusFormatting:
    """Tests for progress status template formatting."""

    def test_progress_status_basic(self, formatter, progress_status):
        """Test basic progress status formatting."""
        result = formatter.format_status(progress_status)
        
        assert isinstance(result, str)
        assert len(result) > 0
        assert 'building' in result.lower() or 'api' in result.lower()

    def test_progress_includes_percentage(self, formatter):
        """Test that progress percentage is included in output."""
        status = {
            'status': 'running',
            'task': 'compiling_code',
            'progress': 50,
            'eta_minutes': 10
        }
        result = formatter.format_status(status)
        
        assert '50' in result or 'fifty' in result.lower()

    def test_progress_includes_eta(self, formatter):
        """Test that ETA is included in output."""
        status = {
            'status': 'running',
            'task': 'compiling_code',
            'progress': 50,
            'eta_minutes': 10
        }
        result = formatter.format_status(status)
        
        assert '10' in result or 'ten' in result.lower()

    def test_progress_zero_percent(self, formatter):
        """Test progress at 0 percent."""
        status = {
            'status': 'running',
            'task': 'initialising',
            'progress': 0,
            'eta_minutes': 30
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)
        assert '0' in result or 'starting' in result.lower() or 'begin' in result.lower()

    def test_progress_100_percent(self, formatter):
        """Test progress at 100 percent."""
        status = {
            'status': 'running',
            'task': 'finalising',
            'progress': 100,
            'eta_minutes': 0
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)
        assert '100' in result or 'complete' in result.lower() or 'finished' in result.lower()


# ============================================================================
# UNIT TESTS - Queue Status Formatting
# ============================================================================

class TestQueueStatusFormatting:
    """Tests for queue status template formatting."""

    def test_queue_status_basic(self, formatter, queue_status):
        """Test basic queue status formatting."""
        result = formatter.format_status(queue_status)
        
        assert isinstance(result, str)
        assert len(result) > 0

    def test_queue_pending_count(self, formatter):
        """Test pending directives count is included."""
        status = {
            'pending_directives': 5,
            'completed_today': 10,
            'failed': 0
        }
        result = formatter.format_status(status)
        
        assert '5' in result or 'five' in result.lower()

    def test_queue_completed_today(self, formatter):
        """Test completed today count is included."""
        status = {
            'pending_directives': 5,
            'completed_today': 10,
            'failed': 0
        }
        result = formatter.format_status(status)
        
        assert '10' in result or 'ten' in result.lower()

    def test_queue_failed_count(self, formatter):
        """Test failed count is included."""
        status = {
            'pending_directives': 5,
            'completed_today': 10,
            'failed': 2
        }
        result = formatter.format_status(status)
        
        assert '2' in result or 'two' in result.lower()

    def test_queue_zero_pending(self, formatter):
        """Test queue with zero pending items."""
        status = {
            'pending_directives': 0,
            'completed_today': 10,
            'failed': 0
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_queue_large_numbers(self, formatter):
        """Test queue with large numbers."""
        status = {
            'pending_directives': 150,
            'completed_today': 500,
            'failed': 25
        }
        result = formatter.format_status(status)
        
        assert '150' in result
        assert '500' in result
        assert '25' in result


# ============================================================================
# UNIT TESTS - Error Status Formatting
# ============================================================================

class TestErrorStatusFormatting:
    """Tests for error status template formatting."""

    def test_error_status_basic(self, formatter, error_status):
        """Test basic error status formatting."""
        result = formatter.format_status(error_status)
        
        assert isinstance(result, str)
        assert len(result) > 0

    def test_error_retry_included(self, formatter):
        """Test retry duration is included in output."""
        status = {
            'error': 'timeout',
            'retry_in': 60
        }
        result = formatter.format_status(status)
        
        assert '60' in result or 'sixty' in result.lower()

    def test_error_database_connection(self, formatter):
        """Test database connection error formatting."""
        status = {
            'error': 'database_connection_failed',
            'retry_in': 30
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)
        assert 'database' in result.lower() or 'connection' in result.lower()

    def test_error_timeout(self, formatter):
        """Test timeout error formatting."""
        status = {
            'error': 'request_timeout',
            'retry_in': 15
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_error_authentication(self, formatter):
        """Test authentication error formatting."""
        status = {
            'error': 'authentication_failed',
            'retry_in': 0
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_error_zero_retry(self, formatter):
        """Test error with zero retry time."""
        status = {
            'error': 'success',
            'retry_in': 0
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)


# ============================================================================
# UNIT TESTS - Completion Status Formatting
# ============================================================================

class TestCompletionStatusFormatting:
    """Tests for completion status template formatting."""

    def test_completion_status_basic(self, formatter, completion_status):
        """Test basic completion status formatting."""
        result = formatter.format_status(completion_status)
        
        assert isinstance(result, str)
        assert len(result) > 0

    def test_completion_includes_duration(self, formatter):
        """Test duration is included in completion output."""
        status = {
            'status': 'completed',
            'task': 'data_migration',
            'duration_minutes': 45,
            'items_processed': 1250
        }
        result = formatter.format_status(status)
        
        assert '45' in result or 'forty-five' in result.lower() or '45' in result

    def test_completion_includes_items(self, formatter):
        """Test items processed is included in output."""
        status = {
            'status': 'completed',
            'task': 'data_migration',
            'duration_minutes': 45,
            'items_processed': 1250
        }
        result = formatter.format_status(status)
        
        assert '1250' in result or '1,250' in result

    def test_completion_zero_duration(self, formatter):
        """Test completion with zero duration."""
        status = {
            'status': 'completed',
            'task': 'quick_task',
            'duration_minutes': 0,
            'items_processed': 5
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_completion_large_items(self, formatter):
        """Test completion with large item count."""
        status = {
            'status': 'completed',
            'task': 'bulk_processing',
            'duration_minutes': 120,
            'items_processed': 100000
        }
        result = formatter.format_status(status)
        
        assert '100000' in result or '100,000' in result


# ============================================================================
# UNIT TESTS - System Health Formatting
# ============================================================================

class TestSystemHealthFormatting:
    """Tests for system health template formatting."""

    def test_system_health_basic(self, formatter, system_health_status):
        """Test basic system health formatting."""
        result = formatter.format_status(system_health_status)
        
        assert isinstance(result, str)
        assert len(result) > 0

    def test_system_health_cpu(self, formatter):
        """Test CPU usage is included."""
        status = {
            'cpu_usage': 85,
            'memory_usage': 50,
            'disk_usage': 40,
            'active_connections': 5
        }
        result = formatter.format_status(status)
        
        assert '85' in result or 'eighty-five' in result.lower()

    def test_system_health_memory(self, formatter):
        """Test memory usage is included."""
        status = {
            'cpu_usage': 50,
            'memory_usage': 75,
            'disk_usage': 40,
            'active_connections': 5
        }
        result = formatter.format_status(status)
        
        assert '75' in result or 'seventy-five' in result.lower()

    def test_system_health_disk(self, formatter):
        """Test disk usage is included."""
        status = {
            'cpu_usage': 50,
            'memory_usage': 50,
            'disk_usage': 90,
            'active_connections': 5
        }
        result = formatter.format_status(status)
        
        assert '90' in result or 'ninety' in result.lower()

    def test_system_health_connections(self, formatter):
        """Test active connections are included."""
        status = {
            'cpu_usage': 50,
            'memory_usage': 50,
            'disk_usage': 40,
            'active_connections': 25
        }
        result = formatter.format_status(status)
        
        assert '25' in result or 'twenty-five' in result.lower()

    def test_system_health_high_cpu_alert(self, formatter):
        """Test high CPU triggers alert tone."""
        status = {
            'cpu_usage': 95,
            'memory_usage': 50,
            'disk_usage': 40,
            'active_connections': 5
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)
        # High CPU should be mentioned prominently

    def test_system_health_low_resources(self, formatter):
        """Test system with low resource usage."""
        status = {
            'cpu_usage': 10,
            'memory_usage': 20,
            'disk_usage': 15,
            'active_connections': 1
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)


# ============================================================================
# EDGE CASE TESTS
# ============================================================================

class TestEdgeCases:
    """Tests for edge cases and error handling."""

    def test_empty_status(self, formatter, empty_status):
        """Test empty status data returns fallback."""
        result = formatter.format_status(empty_status)
        
        assert isinstance(result, str)
        assert len(result) > 0

    def test_none_status(self, formatter):
        """Test None status data returns fallback."""
        result = formatter.format_status(None)
        
        assert isinstance(result, str)

    def test_malformed_numbers(self, formatter, malformed_status):
        """Test handling of malformed number values."""
        result = formatter.format_status(malformed_status)
        
        assert isinstance(result, str)

    def test_missing_optional_fields(self, formatter):
        """Test status with missing optional fields."""
        status = {'status': 'running'}
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_extra_fields_ignored(self, formatter):
        """Test that extra fields are ignored."""
        status = {
            'status': 'running',
            'task': 'testing',
            'progress': 50,
            'unknown_field': 'should_be_ignored',
            'another_unknown': 12345
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)
        assert 'should_be_ignored' not in result
        assert '12345' in result  # progress value should still appear

    def test_negative_numbers(self, formatter):
        """Test handling of negative numbers."""
        status = {
            'status': 'running',
            'progress': -5,
            'eta_minutes': -1
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_very_large_numbers(self, formatter):
        """Test handling of very large numbers."""
        status = {
            'pending_directives': 999999999,
            'completed_today': 888888888,
            'failed': 777777777
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_floating_point_numbers(self, formatter):
        """Test handling of floating point numbers."""
        status = {
            'cpu_usage': 75.5,
            'memory_usage': 62.3,
            'progress': 33.33
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_special_characters_in_task(self, formatter):
        """Test handling of special characters in task names."""
        status = {
            'status': 'running',
            'task': 'process_file_@#$%',
            'progress': 50
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_unicode_in_task(self, formatter):
        """Test handling of unicode characters in task names."""
        status = {
            'status': 'running',
            'task': 'Processing Māori data 日記',
            'progress': 50
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)


# ============================================================================
# UNKNOWN STATUS TYPE TESTS
# ============================================================================

class TestUnknownStatusTypes:
    """Tests for unknown status type handling and fallbacks."""

    def test_unknown_status_type(self, formatter):
        """Test fallback for unknown status type."""
        status = {
            'unknown_field': 'some_value',
            'another_field': 42
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)
        assert len(result) > 0

    def test_arbitrary_status_structure(self, formatter):
        """Test handling of arbitrary status structures."""
        status = {
            'custom_status': 'active',
            'metric_one': 100,
            'metric_two': 200,
            'metric_three': 300
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_mixed_known_and_unknown(self, formatter):
        """Test status with mix of known and unknown fields."""
        status = {
            'status': 'running',
            'progress': 50,
            'custom_field': 'value',
            'another_custom': 999
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)


# ============================================================================
# TEMPLATE TESTS
# ============================================================================

class TestTemplateFormatting:
    """Tests for specific template functionality."""

    def test_template_variables_substituted(self, formatter):
        """Test that template variables are properly substituted."""
        status = {
            'status': 'running',
            'task': 'test_task',
            'progress': 75,
            'eta_minutes': 5
        }
        result = formatter.format_status(status)
        
        # Should not contain template placeholders
        assert '{' not in result
        assert '}' not in result
        assert 'variable' not in result.lower()

    def test_australian_friendly_language(self, formatter):
        """Test that output uses Australian-friendly language."""
        status = {
            'status': 'completed',
            'task': 'processing',
            'duration_minutes': 30
        }
        result = formatter.format_status(status)
        
        # Should be conversational
        assert isinstance(result, str)
        # Check for natural language patterns
        assert any(char.isalpha() for char in result)

    def test_natural_number_spelling(self, formatter):
        """Test natural spelling of small numbers."""
        status = {
            'pending_directives': 1,
            'completed_today': 2,
            'failed': 0
        }
        result = formatter.format_status(status)
        
        assert isinstance(result, str)

    def test_time_duration_handling(self, formatter):
        """Test various time duration formats."""
        test_cases = [
            {'eta_minutes': 1},
            {'eta_minutes': 30},
            {'eta_minutes': 60},
            {'eta_minutes': 120},
            {'duration_minutes': 90},
        ]
        
        for case in test_cases:
            case['status'] = 'running'
            case['task'] = 'test'
            result = formatter.format_status(case)
            assert isinstance(result, str)


# ============================================================================
# INTEGRATION TESTS
# ============================================================================

class TestIntegration:
    """Integration tests for the formatter module."""

    def test_full_workflow_progress_to_completion(self, formatter):
        """Test full workflow from progress to completion."""
        # Starting
        progress_status = {
            'status': 'running',
            'task': 'building_api',
            'progress': 10,
            'eta_minutes': 60
        }
        result1 = formatter.format_status(progress_status)
        assert isinstance(result1, str)
        
        # Mid-progress
        progress_status['progress'] = 50
        progress_status['eta_minutes'] = 30
        result2 = formatter.format_status(progress_status)
        assert isinstance(result2, str)
        
        # Complete
        completion_status = {
            'status': 'completed',
            'task': 'building_api',
            'duration_minutes': 55,
            'items_processed': 500
        }
        result3 = formatter.format_status(completion_status)
        assert isinstance(result3, str)

    def test_error_recovery_workflow(self, formatter):
        """Test workflow with error and recovery."""
        # Error occurs
        error_status = {
            'error': 'connection_failed',
            'retry_in': 30
        }
        result1 = formatter.format_status(error_status)
        assert isinstance(result1, str)
        
        # Retry
        error_status['retry_in'] = 10
        result2 = formatter.format_status(error_status)
        assert isinstance(result2, str)
        
        # Success
        success_status = {
            'status': 'completed',
            'task': 'reconnecting',
            'duration_minutes': 1
        }
        result3 = formatter.format_status(success_status)
        assert isinstance(result3, str)

    def test_queue_management_workflow(self, formatter):
        """Test queue management status workflow."""
        # High queue
        queue_status = {
            'pending_directives': 50,
            'completed_today': 10,
            'failed': 5
        }
        result1 = formatter.format_status(queue_status)
        assert isinstance(result1, str)
        
        # Processing
        queue_status['pending_directives'] = 25
        queue_status['completed_today'] = 35
        result2 = formatter.format_status(queue_status)
        assert isinstance(result2, str)
        
        # Cleared
        queue_status['pending_directives'] = 0
        queue_status['completed_today'] = 50
        queue_status['failed'] = 5
        result3 = formatter.format_status(queue_status)
        assert isinstance(result3, str)

    def test_multiple_formats_in_sequence(self, formatter):
        """Test multiple different status formats in sequence."""
        statuses = [
            {'status': 'running', 'task': 'task1', 'progress': 10, 'eta_minutes': 50},
            {'error': 'test_error', 'retry_in': 5},
            {'pending_directives': 3, 'completed_today': 10, 'failed': 1},
            {'cpu_usage': 50, 'memory_usage': 50, 'disk_usage': 50, 'active_connections': 5},
            {'status': 'completed', 'task': 'task1', 'duration_minutes': 45},
            {},
            {'unknown': 'unknown'}
        ]
        
        for status in statuses:
            result = formatter.format_status(status)
            assert isinstance(result, str)
            assert len(result) > 0


# ============================================================================
# PERFORMANCE AND ROBUSTNESS TESTS
# ============================================================================

class TestPerformanceAndRobustness:
    """Tests for performance and robustness."""

    def test_repeated_calls_consistent(self, formatter):
        """Test that repeated calls return consistent results."""
        status = {
            'status': 'running',
            'task': 'test',
            'progress': 50,
            'eta_minutes': 10
        }
        
        results = [formatter.format_status(status) for _ in range(10)]
        
        # All results should be strings
        assert all(isinstance(r, str) for r in results)

    def test_rapid_sequential_calls(self, formatter):
        """Test rapid sequential calls don't fail."""
        status = {'status': 'running', 'task': 'test', 'progress': 50}
        
        for _ in range(100):
            result = formatter.format_status(status)
            assert isinstance(result, str)

    def test_various_status_combinations(self, formatter):
        """Test various combinations of status fields."""
        combinations = [
            {'progress': 0},
            {'progress': 100},
            {'progress': 50, 'eta_minutes': 0},
            {'error': 'test'},
            {'pending_directives': 0},
            {'completed_today': 0},
            {'failed': 0},
            {'cpu_usage': 0},
            {'cpu_usage': 100},
            {'memory_usage': 0},
            {'memory_usage': 100},
            {'disk_usage': 0},
            {'disk_usage': 100},
        ]
        
        for combo in combinations:
            result = formatter.format_status(combo)
            assert isinstance(result, str)


# ============================================================================
# TEST CONFIGURATION AND UTILITIES
# ============================================================================

class TestConfiguration:
    """Tests for formatter configuration."""

    def test_formatter_initialization(self):
        """Test formatter can be initialized."""
        from status_formatter import StatusFormatter
        formatter = StatusFormatter()
        assert formatter is not None

    def test_formatter_has_format_method(self, formatter):
        """Test formatter has format_status method."""
        assert hasattr(formatter, 'format_status')
        assert callable(formatter.format_status)

    def test_formatter_has_template_methods(self, formatter):
        """Test formatter has template methods."""
        # Check for template handling methods if they exist
        assert hasattr(formatter, 'format_status') or hasattr(formatter, 'format')


# ============================================================================
# RUN TESTS WITH: pytest test_status_formatter.py -v --cov=status_formatter --cov-report=term-missing
# ============================================================================