from pathlib import Path
import tempfile
import pytest
import yaml
from utils import config


def test_path_config():
    pc = config.PathConfig(work_dir='/tmp', web_folder='/web')
    assert pc.work_dir == '/tmp'
    assert pc.web_folder == '/web'


def test_gallery_config():
    gc = config.GalleryConfig(
        plot_root='plots', png_dpi=150, backup_folder='backups')
    assert gc.plot_root == 'plots'
    assert gc.png_dpi == 150
    assert gc.backup_folder == 'backups'


def test_ui_config():
    ui = config.UIConfig(max_recent_plots=10, search_debounce_ms=200)
    assert ui.max_recent_plots == 10
    assert ui.search_debounce_ms == 200


def test_metadata_config_defaults():
    mc = config.MetadataConfig()
    assert mc.cache_enabled is True
    assert mc.inherit_from_parent is True
    assert mc.supported_formats == ['.yaml', '.yml', '.json']


def test_metadata_config_custom():
    mc = config.MetadataConfig(
        cache_enabled=False,
        inherit_from_parent=False,
        supported_formats=['.yaml']
    )
    assert mc.cache_enabled is False
    assert mc.inherit_from_parent is False
    assert mc.supported_formats == ['.yaml']


def test_gallery_item():
    item = config.GalleryItem(name="test", path=Path("/test/path"))
    assert item.name == "test"
    assert item.path == Path("/test/path")


def test_config_creation():
    paths = config.PathConfig(work_dir="/work", web_folder="/web")
    gallery = config.GalleryConfig(
        plot_root="plots", png_dpi=300, backup_folder="backups")
    ui = config.UIConfig(max_recent_plots=5, search_debounce_ms=100)
    metadata = config.MetadataConfig()

    cfg = config.Config(
        paths=paths,
        gallery=gallery,
        ui=ui,
        metadata=metadata
    )

    assert cfg.paths == paths
    assert cfg.gallery == gallery
    assert cfg.ui == ui
    assert cfg.metadata == metadata
    assert cfg.sources == []


def test_config_backward_compatibility_properties():
    paths = config.PathConfig(work_dir="/work", web_folder="/web")
    gallery = config.GalleryConfig(
        plot_root="plots", png_dpi=300, backup_folder="backups")
    ui = config.UIConfig(max_recent_plots=5, search_debounce_ms=100)
    metadata = config.MetadataConfig()

    cfg = config.Config(
        paths=paths,
        gallery=gallery,
        ui=ui,
        metadata=metadata
    )

    assert cfg.web_folder == "/web"
    assert cfg.png_dpi == 300
    assert cfg.plot_root == "plots"
    assert cfg.backup_folder == "backups"


def test_config_from_yaml(tmp_path):
    yaml_content = {
        'paths': {
            'work_dir': '/test/work',
            'web_folder': '/test/web'
        },
        'gallery': {
            'plot_root': 'test_plots',
            'png_dpi': 200,
            'backup_folder': 'test_backups'
        },
        'ui': {
            'max_recent_plots': 15,
            'search_debounce_ms': 300
        },
        'metadata': {
            'cache_enabled': False,
            'inherit_from_parent': False
        },
        'sources': [
            {'name': 'source1', 'path': '/path1'},
            {'name': 'source2', 'path': '/path2'}
        ]
    }

    yaml_file = tmp_path / 'test_config.yaml'
    with yaml_file.open('w') as f:
        yaml.dump(yaml_content, f)

    cfg = config.Config.from_yaml(str(yaml_file))

    assert cfg.paths.work_dir == '/test/work'
    assert cfg.paths.web_folder == '/test/web'
    assert cfg.gallery.plot_root == 'test_plots'
    assert cfg.gallery.png_dpi == 200
    assert cfg.ui.max_recent_plots == 15
    assert cfg.metadata.cache_enabled is False
    assert len(cfg.sources) == 2
    assert cfg.sources[0].name == 'source1'
    assert cfg.sources[0].path == Path('/path1')


def test_config_from_yaml_missing_file():
    with pytest.raises(FileNotFoundError):
        config.Config.from_yaml('/nonexistent/file.yaml')


def test_config_from_yaml_malformed():
    with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml',
                                     delete=False) as f:
        f.write('invalid: yaml: content: [')
        f.flush()

        with pytest.raises(yaml.YAMLError):
            config.Config.from_yaml(f.name)


def test_config_to_yaml(tmp_path):
    paths = config.PathConfig(work_dir="/work", web_folder="/web")
    gallery = config.GalleryConfig(
        plot_root="plots", png_dpi=300, backup_folder="backups")
    ui = config.UIConfig(max_recent_plots=5, search_debounce_ms=100)
    metadata = config.MetadataConfig()
    sources = [config.GalleryItem(name="test", path=Path("/test"))]

    cfg = config.Config(
        paths=paths,
        gallery=gallery,
        ui=ui,
        metadata=metadata,
        sources=sources
    )

    yaml_file = tmp_path / 'output_config.yaml'
    cfg.to_yaml(str(yaml_file))

    assert yaml_file.exists()

    # Just verify the file contains expected content (no Path parsing)
    content = yaml_file.read_text()
    assert 'work_dir: /work' in content
    assert 'png_dpi: 300' in content
    assert 'name: test' in content


def test_config_from_yaml_partial_data(tmp_path):
    # Test with minimal YAML data
    yaml_content = {
        'paths': {'work_dir': '/min', 'web_folder': '/min_web'},
        'gallery': {'plot_root': 'min_plots', 'png_dpi': 100,
                    'backup_folder': 'min_backup'},
        'ui': {'max_recent_plots': 3, 'search_debounce_ms': 50}
    }

    yaml_file = tmp_path / 'minimal_config.yaml'
    with yaml_file.open('w') as f:
        yaml.dump(yaml_content, f)

    cfg = config.Config.from_yaml(str(yaml_file))

    # Should use defaults for metadata and empty sources
    assert cfg.metadata.cache_enabled is True  # default
    assert cfg.sources == []  # default empty list
