"""Unit tests for configuration system."""

import os

import pytest

from webdrop_bridge.config import Config, ConfigurationError


@pytest.fixture(autouse=True)
def clear_env():
    """Clear environment variables before each test to avoid persistence."""
    # Save current env
    saved_env = os.environ.copy()
    
    # Clear relevant variables
    for key in list(os.environ.keys()):
        if key.startswith(('APP_', 'LOG_', 'ALLOWED_', 'WEBAPP_', 'WINDOW_', 'ENABLE_')):
            del os.environ[key]
    
    yield
    
    # Restore env (cleanup)
    os.environ.clear()
    os.environ.update(saved_env)


class TestConfigFromEnv:
    """Test Config.from_env() loading from environment."""

    def test_from_env_with_all_values(self, tmp_path):
        """Test loading config with all environment variables set."""
        # Create .env file
        env_file = tmp_path / ".env"
        root1 = tmp_path / "root1"
        root2 = tmp_path / "root2"
        root1.mkdir()
        root2.mkdir()

        env_file.write_text(
            f"APP_NAME=TestApp\n"
            f"APP_VERSION=2.0.0\n"
            f"LOG_LEVEL=DEBUG\n"
            f"LOG_FILE={tmp_path / 'test.log'}\n"
            f"ALLOWED_ROOTS={root1},{root2}\n"
            f"ALLOWED_URLS=example.com,*.test.org\n"
            f"WEBAPP_URL=http://localhost:8000\n"
            f"WINDOW_WIDTH=1200\n"
            f"WINDOW_HEIGHT=800\n"
        )

        # Load config (env vars from file, not system)
        config = Config.from_env(str(env_file))

        assert config.app_name == "TestApp"
        assert config.app_version == "2.0.0"
        assert config.log_level == "DEBUG"
        assert config.allowed_roots == [root1.resolve(), root2.resolve()]
        assert config.allowed_urls == ["example.com", "*.test.org"]
        assert config.webapp_url == "http://localhost:8000"
        assert config.window_width == 1200
        assert config.window_height == 800

    def test_from_env_with_defaults(self, tmp_path):
        """Test loading config uses defaults when env vars not set."""
        # Create empty .env file
        env_file = tmp_path / ".env"
        env_file.write_text("")

        config = Config.from_env(str(env_file))

        assert config.app_name == "WebDrop Bridge"
        # Version should come from __init__.py (dynamic, not hardcoded)
        from webdrop_bridge import __version__
        assert config.app_version == __version__
        assert config.log_level == "INFO"
        assert config.window_width == 1024
        assert config.window_height == 768

    def test_from_env_invalid_log_level(self, tmp_path):
        """Test that invalid log level raises ConfigurationError."""
        env_file = tmp_path / ".env"
        root1 = tmp_path / "root1"
        root1.mkdir()
        env_file.write_text(f"LOG_LEVEL=INVALID\nALLOWED_ROOTS={root1}\n")

        with pytest.raises(ConfigurationError, match="Invalid LOG_LEVEL"):
            Config.from_env(str(env_file))

    def test_from_env_invalid_window_dimension(self, tmp_path):
        """Test that negative window dimensions raise ConfigurationError."""
        env_file = tmp_path / ".env"
        root1 = tmp_path / "root1"
        root1.mkdir()
        env_file.write_text(f"WINDOW_WIDTH=-100\nALLOWED_ROOTS={root1}\n")

        with pytest.raises(ConfigurationError, match="Window dimensions"):
            Config.from_env(str(env_file))

    def test_from_env_invalid_root_path(self, tmp_path):
        """Test that non-existent root paths are logged as warning but don't raise error."""
        env_file = tmp_path / ".env"
        env_file.write_text("ALLOWED_ROOTS=/nonexistent/path/that/does/not/exist\n")

        # Should not raise - just logs warning and returns empty allowed_roots
        config = Config.from_env(str(env_file))
        assert config.allowed_roots == []  # Non-existent roots are skipped

    def test_from_env_empty_webapp_url(self, tmp_path):
        """Test that empty webapp URL raises ConfigurationError."""
        env_file = tmp_path / ".env"
        root1 = tmp_path / "root1"
        root1.mkdir()
        env_file.write_text(f"WEBAPP_URL=\nALLOWED_ROOTS={root1}\n")

        with pytest.raises(ConfigurationError, match="WEBAPP_URL"):
            Config.from_env(str(env_file))


class TestConfigValidation:
    """Test Config field validation."""

    def test_root_path_resolution(self, tmp_path):
        """Test that root paths are resolved to absolute paths."""
        env_file = tmp_path / ".env"
        root_dir = tmp_path / "allowed"
        root_dir.mkdir()

        env_file.write_text(f"ALLOWED_ROOTS={root_dir}\n")

        config = Config.from_env(str(env_file))

        # Should be resolved to absolute path
        assert config.allowed_roots[0].is_absolute()

    def test_multiple_root_paths(self, tmp_path):
        """Test loading multiple root paths."""
        dir1 = tmp_path / "dir1"
        dir2 = tmp_path / "dir2"
        dir1.mkdir()
        dir2.mkdir()

        env_file = tmp_path / ".env"
        env_file.write_text(f"ALLOWED_ROOTS={dir1},{dir2}\n")

        config = Config.from_env(str(env_file))

        assert len(config.allowed_roots) == 2
        assert config.allowed_roots[0] == dir1.resolve()
        assert config.allowed_roots[1] == dir2.resolve()

    def test_allowed_urls_empty(self, tmp_path):
        """Test that empty ALLOWED_URLS means no URL restriction."""
        env_file = tmp_path / ".env"
        env_file.write_text("ALLOWED_URLS=\n")

        config = Config.from_env(str(env_file))

        assert config.allowed_urls == []

    def test_allowed_urls_single(self, tmp_path):
        """Test loading single allowed URL."""
        env_file = tmp_path / ".env"
        env_file.write_text("ALLOWED_URLS=example.com\n")

        config = Config.from_env(str(env_file))

        assert config.allowed_urls == ["example.com"]

    def test_allowed_urls_multiple(self, tmp_path):
        """Test loading multiple allowed URLs."""
        env_file = tmp_path / ".env"
        env_file.write_text("ALLOWED_URLS=example.com,*.test.org,localhost\n")

        config = Config.from_env(str(env_file))

        assert config.allowed_urls == ["example.com", "*.test.org", "localhost"]

    def test_allowed_urls_with_whitespace(self, tmp_path):
        """Test that whitespace is trimmed from allowed URLs."""
        env_file = tmp_path / ".env"
        env_file.write_text("ALLOWED_URLS= example.com , test.org \n")

        config = Config.from_env(str(env_file))

        assert config.allowed_urls == ["example.com", "test.org"]
