"""Tests for logging module."""

import os
from pathlib import Path
from unittest.mock import patch

import pytest

from scry_run.logging import ScryRunLogger, get_logger


class TestScryRunLogger:
    """Tests for ScryRunLogger."""

    def test_log_dir_from_env(self, tmp_path):
        """Test log directory can be set via environment."""
        log_dir = tmp_path / "logs"
        log_dir.mkdir()

        with patch.dict(os.environ, {"SCRY_LOG_DIR": str(log_dir)}):
            # Reset singleton
            ScryRunLogger._instance = None
            logger = get_logger()

            logger.info("test message")

            # Log file is now timestamped, check via logger.log_file
            assert logger.log_file.exists()
            assert "test message" in logger.log_file.read_text()

    def test_default_log_file_name(self, tmp_path):
        """Test default log file is timestamped."""
        with patch.dict(os.environ, {"SCRY_LOG_DIR": str(tmp_path)}):
            ScryRunLogger._instance = None
            logger = get_logger()

            # Log file is now timestamped: generation_YYYYMMDD_HHMMSS.log
            assert logger.log_file.name.startswith("generation_")
            assert logger.log_file.name.endswith(".log")

    def test_log_disabled_by_env(self, tmp_path):
        """Test logging can be disabled via SCRY_DEBUG=0."""
        log_dir = tmp_path / "logs"
        log_dir.mkdir()

        with patch.dict(os.environ, {
            "SCRY_LOG_DIR": str(log_dir),
            "SCRY_DEBUG": "0",
        }):
            ScryRunLogger._instance = None
            logger = get_logger()
            logger.info("should not appear")
            # No log file created when disabled
            assert not logger.log_file.exists()

    def test_log_levels(self, tmp_path):
        """Test different log levels work."""
        with patch.dict(os.environ, {"SCRY_LOG_DIR": str(tmp_path)}):
            ScryRunLogger._instance = None
            logger = get_logger()

            logger.debug("debug message")
            logger.info("info message")
            logger.warn("warn message")
            logger.error("error message")

            content = logger.log_file.read_text()
            assert "[DEBUG]" in content
            assert "[INFO]" in content
            assert "[WARN]" in content
            assert "[ERROR]" in content

    def test_set_app_context_creates_logs_dir(self, tmp_path):
        """Test set_app_context creates logs/ subdirectory."""
        ScryRunLogger._instance = None
        logger = ScryRunLogger()
        
        app_dir = tmp_path / "my_app"
        app_dir.mkdir()
        
        logger.set_app_context(app_dir)
        logger.info("test message")
        
        # Should create logs/ subdirectory
        logs_dir = app_dir / "logs"
        assert logs_dir.exists()
        
        # Log file should be in logs/
        assert logger.log_file.parent == logs_dir
        assert logger.log_file.exists()

    def test_set_log_dir(self, tmp_path):
        """Test set_log_dir sets custom directory."""
        ScryRunLogger._instance = None
        logger = ScryRunLogger()
        
        custom_dir = tmp_path / "custom_logs"
        logger.set_log_dir(custom_dir)
        logger.info("test message")
        
        # Directory should be created
        assert custom_dir.exists()
        
        # Log file should be in custom directory
        assert logger.log_file.parent == custom_dir
        assert logger.log_file.exists()

    def test_timestamped_log_files_unique_per_session(self, tmp_path):
        """Test that each logger instance gets unique timestamped file."""
        import time
        
        ScryRunLogger._instance = None
        logger1 = ScryRunLogger(tmp_path)
        name1 = logger1.log_file.name
        
        # Small delay to ensure different timestamp
        time.sleep(1.1)
        
        ScryRunLogger._instance = None
        logger2 = ScryRunLogger(tmp_path)
        name2 = logger2.log_file.name
        
        # Both should have timestamped names
        assert name1.startswith("generation_")
        assert name2.startswith("generation_")
        
        # Names should be different (different sessions)
        assert name1 != name2

    def test_log_file_contains_timestamp_format(self, tmp_path):
        """Test log filename matches expected timestamp format."""
        import re
        
        with patch.dict(os.environ, {"SCRY_LOG_DIR": str(tmp_path)}):
            ScryRunLogger._instance = None
            logger = get_logger()
            
            # Should match format: generation_YYYYMMDD_HHMMSS.log
            pattern = r"generation_\d{8}_\d{6}\.log"
            assert re.match(pattern, logger.log_file.name)
