"""Tests for configuration loading and parsing."""

import pytest
import json
import yaml
import tempfile
from pathlib import Path

from generate import load_config, parse_range


class TestConfigLoading:
    """Test configuration file loading."""
    
    def test_load_yaml_config(self, temp_dir):
        """Test loading YAML configuration files."""
        config_data = {
            'range': '0-9',
            'cards_per_page': 4,
            'bead_shape': 'circle'
        }
        
        config_file = temp_dir / 'test.yaml'
        with open(config_file, 'w') as f:
            yaml.dump(config_data, f)
        
        loaded = load_config(str(config_file))
        assert loaded == config_data
    
    def test_load_json_config(self, temp_dir):
        """Test loading JSON configuration files."""
        config_data = {
            'range': '0-99',
            'color_scheme': 'place-value',
            'margins': {'top': '1in', 'bottom': '1in'}
        }
        
        config_file = temp_dir / 'test.json'
        with open(config_file, 'w') as f:
            json.dump(config_data, f)
        
        loaded = load_config(str(config_file))
        assert loaded == config_data
    
    def test_load_nonexistent_config(self):
        """Test handling of nonexistent config files."""
        with pytest.raises(FileNotFoundError):
            load_config('nonexistent.yaml')


class TestRangeParsing:
    """Test number range parsing functionality."""
    
    def test_parse_simple_range(self):
        """Test parsing simple ranges like '0-9'."""
        result = parse_range('0-9')
        expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        assert result == expected
    
    def test_parse_range_with_step(self):
        """Test parsing ranges with custom steps."""
        result = parse_range('0-10', step=2)
        expected = [0, 2, 4, 6, 8, 10]
        assert result == expected
        
        result = parse_range('0-20', step=5)
        expected = [0, 5, 10, 15, 20]
        assert result == expected
    
    def test_parse_comma_list(self):
        """Test parsing comma-separated number lists."""
        result = parse_range('1,5,10,25')
        expected = [1, 5, 10, 25]
        assert result == expected
    
    def test_parse_mixed_list_and_ranges(self):
        """Test parsing mixed comma-separated values with ranges."""
        result = parse_range('1,5-7,10')
        expected = [1, 5, 6, 7, 10]
        assert result == expected
    
    def test_parse_single_number(self):
        """Test parsing single numbers."""
        result = parse_range('42')
        expected = [42]
        assert result == expected
    
    def test_parse_negative_numbers(self):
        """Test handling of negative numbers (edge case)."""
        # Note: The current implementation might not handle this correctly
        # This test documents the expected behavior
        with pytest.raises(ValueError):
            parse_range('-5-5')
    
    def test_parse_invalid_range(self):
        """Test handling of invalid range strings."""
        with pytest.raises(ValueError):
            parse_range('invalid')
        
        # Range where start > end results in empty list (valid behavior)
        result = parse_range('10-5')
        assert result == []
    
    def test_parse_large_range(self):
        """Test parsing large ranges."""
        result = parse_range('0-100', step=25)
        expected = [0, 25, 50, 75, 100]
        assert result == expected
    
    def test_parse_step_ignored_for_lists(self):
        """Test that step parameter is ignored for comma-separated lists."""
        result = parse_range('1,2,3,4', step=10)  # Step should be ignored
        expected = [1, 2, 3, 4]
        assert result == expected


class TestConfigIntegration:
    """Integration tests for configuration handling."""
    
    def test_real_config_files(self, project_root):
        """Test loading real configuration files from the project."""
        config_dir = project_root / 'config'
        
        # Test default config
        default_config = config_dir / 'default.yaml'
        if default_config.exists():
            config = load_config(str(default_config))
            assert 'range' in config
            assert 'cards_per_page' in config
    
    def test_config_with_range_parsing(self, temp_dir):
        """Test integration of config loading with range parsing."""
        config_data = {
            'range': '5-15',
            'step': 2,
            'cards_per_page': 8
        }
        
        config_file = temp_dir / 'test.yaml'
        with open(config_file, 'w') as f:
            yaml.dump(config_data, f)
        
        config = load_config(str(config_file))
        numbers = parse_range(config['range'], config.get('step', 1))
        
        expected = [5, 7, 9, 11, 13, 15]
        assert numbers == expected
    
    def test_config_defaults(self, sample_config):
        """Test that sample config has reasonable defaults."""
        assert sample_config['cards_per_page'] > 0
        assert sample_config['scale_factor'] > 0
        assert sample_config['bead_shape'] in ['diamond', 'circle', 'square']
        assert sample_config['color_scheme'] in ['monochrome', 'place-value', 'heaven-earth', 'alternating']