"""
Tests for configuration module.
"""

import pytest
import tempfile
from pathlib import Path
from unittest.mock import patch

from soracli.config import (
    SoraConfig, load_config, save_config, init_config,
    load_theme, list_themes, get_default_theme, _parse_simple_yaml,
)


class TestSoraConfig:
    """Tests for SoraConfig dataclass."""
    
    def test_default_values(self):
        """Test default configuration values."""
        config = SoraConfig()
        assert config.location == 'London'
        assert config.theme == 'default'
        assert config.refresh_rate == 60
        assert config.sound is False
        assert config.units == 'metric'
        assert config.intensity == 1.0
    
    def test_custom_values(self):
        """Test custom configuration values."""
        config = SoraConfig(
            location='Tokyo',
            theme='cyberpunk',
            refresh_rate=120,
            sound=True,
            units='imperial'
        )
        assert config.location == 'Tokyo'
        assert config.theme == 'cyberpunk'
        assert config.refresh_rate == 120
        assert config.sound is True
        assert config.units == 'imperial'
    
    def test_validation_refresh_rate(self):
        """Test refresh rate validation."""
        config = SoraConfig(refresh_rate=0)
        assert config.refresh_rate == 1  # Minimum
        
        config = SoraConfig(refresh_rate=10000)
        assert config.refresh_rate == 3600  # Maximum
    
    def test_validation_units(self):
        """Test units validation."""
        config = SoraConfig(units='invalid')
        assert config.units == 'metric'  # Fallback to default
    
    def test_validation_intensity(self):
        """Test intensity validation."""
        config = SoraConfig(intensity=0.0)
        assert config.intensity == 0.1  # Minimum
        
        config = SoraConfig(intensity=5.0)
        assert config.intensity == 2.0  # Maximum
    
    def test_to_dict(self):
        """Test conversion to dictionary."""
        config = SoraConfig(location='Paris')
        data = config.to_dict()
        assert data['location'] == 'Paris'
        assert 'theme' in data
        assert 'refresh_rate' in data
    
    def test_from_dict(self):
        """Test creation from dictionary."""
        data = {
            'location': 'Berlin',
            'theme': 'minimal',
            'refresh_rate': 90,
        }
        config = SoraConfig.from_dict(data)
        assert config.location == 'Berlin'
        assert config.theme == 'minimal'
        assert config.refresh_rate == 90
    
    def test_from_dict_unknown_keys(self):
        """Test that unknown keys are ignored."""
        data = {
            'location': 'Berlin',
            'unknown_key': 'value',
            'another_unknown': 123,
        }
        config = SoraConfig.from_dict(data)
        assert config.location == 'Berlin'
        assert not hasattr(config, 'unknown_key')


class TestSimpleYamlParser:
    """Tests for simple YAML parser."""
    
    def test_parse_strings(self):
        """Test parsing string values."""
        content = "location: Tokyo\ntheme: cyberpunk"
        result = _parse_simple_yaml(content)
        assert result['location'] == 'Tokyo'
        assert result['theme'] == 'cyberpunk'
    
    def test_parse_integers(self):
        """Test parsing integer values."""
        content = "refresh_rate: 120"
        result = _parse_simple_yaml(content)
        assert result['refresh_rate'] == 120
    
    def test_parse_floats(self):
        """Test parsing float values."""
        content = "intensity: 1.5"
        result = _parse_simple_yaml(content)
        assert result['intensity'] == 1.5
    
    def test_parse_booleans(self):
        """Test parsing boolean values."""
        content = "sound: true\nenabled: false"
        result = _parse_simple_yaml(content)
        assert result['sound'] is True
        assert result['enabled'] is False
    
    def test_parse_null(self):
        """Test parsing null values."""
        content = "api_key: null"
        result = _parse_simple_yaml(content)
        assert result['api_key'] is None
    
    def test_skip_comments(self):
        """Test that comments are skipped."""
        content = "# This is a comment\nlocation: Tokyo"
        result = _parse_simple_yaml(content)
        assert 'location' in result
        assert '#' not in str(result)


class TestThemes:
    """Tests for theme loading."""
    
    def test_default_theme(self):
        """Test default theme content."""
        theme = get_default_theme()
        assert theme['name'] == 'default'
        assert 'rain_colors' in theme
        assert 'snow_colors' in theme
        assert 'foreground' in theme
    
    def test_load_builtin_theme(self):
        """Test loading built-in themes."""
        theme = load_theme('cyberpunk')
        assert theme['name'] == 'cyberpunk'
        
        theme = load_theme('minimal')
        assert theme['name'] == 'minimal'
    
    def test_load_unknown_theme(self):
        """Test loading unknown theme returns default."""
        theme = load_theme('nonexistent_theme')
        assert theme['name'] == 'default'
    
    def test_list_themes(self):
        """Test listing available themes."""
        themes = list_themes()
        assert 'default' in themes
        assert isinstance(themes, list)


class TestConfigIO:
    """Tests for config file I/O."""
    
    def test_save_and_load_config(self):
        """Test saving and loading config through file system."""
        with tempfile.TemporaryDirectory() as tmpdir:
            config_dir = Path(tmpdir) / ".soracli"
            config_file = config_dir / "config.yaml"
            
            with patch('soracli.config.CONFIG_DIR', config_dir):
                with patch('soracli.config.CONFIG_FILE', config_file):
                    original = SoraConfig(
                        location='Sydney',
                        theme='nature',
                        refresh_rate=90
                    )
                    save_config(original)
                    
                    loaded = load_config()
                    assert loaded.location == 'Sydney'
                    assert loaded.theme == 'nature'
                    assert loaded.refresh_rate == 90
