"""Unit tests for log manager."""

import tempfile
from datetime import datetime, timedelta
from pathlib import Path

import pytest

from src.server.utils.log_manager import LogManager, get_log_manager


@pytest.fixture
def temp_log_env():
    """Create temporary log environment."""
    with tempfile.TemporaryDirectory() as tmpdir:
        yield tmpdir


def test_log_manager_initialization(temp_log_env):
    """Test log manager initialization."""
    manager = LogManager(log_dir=temp_log_env)

    assert manager is not None
    assert manager.log_dir.exists()
    assert manager.archived_dir.exists()


def test_get_log_files(temp_log_env):
    """Test getting list of log files."""
    manager = LogManager(log_dir=temp_log_env)

    # Create test log files
    (Path(temp_log_env) / "app.log").write_text("log content 1")
    (Path(temp_log_env) / "error.log").write_text("log content 2")
    (Path(temp_log_env) / "other.txt").write_text("not a log")

    log_files = manager.get_log_files()

    assert len(log_files) == 2
    assert log_files[0].filename in ["app.log", "error.log"]


def test_rotate_log(temp_log_env):
    """Test log file rotation."""
    manager = LogManager(log_dir=temp_log_env)

    log_file = Path(temp_log_env) / "app.log"
    large_content = "x" * (11 * 1024 * 1024)  # 11MB
    log_file.write_text(large_content)

    result = manager.rotate_log("app.log", max_size_bytes=10485760)

    assert result is True
    assert not log_file.exists()  # Original file rotated


def test_rotate_log_not_found(temp_log_env):
    """Test rotation of non-existent log."""
    manager = LogManager(log_dir=temp_log_env)

    result = manager.rotate_log("nonexistent.log")

    assert result is False


def test_rotate_log_small_file(temp_log_env):
    """Test rotation of small log file."""
    manager = LogManager(log_dir=temp_log_env)

    log_file = Path(temp_log_env) / "app.log"
    log_file.write_text("small content")

    result = manager.rotate_log("app.log", max_size_bytes=1048576)

    assert result is False
    assert log_file.exists()


def test_archive_old_logs(temp_log_env):
    """Test archiving old log files."""
    import os
    from datetime import datetime, timedelta
    
    manager = LogManager(log_dir=temp_log_env)

    # Create old and new logs
    old_log = Path(temp_log_env) / "old.log"
    old_log.write_text("old log")
    
    # Set the modification time to 31 days ago
    old_time = (datetime.now() - timedelta(days=31)).timestamp()
    os.utime(old_log, (old_time, old_time))

    new_log = Path(temp_log_env) / "new.log"
    new_log.write_text("new log")

    archived = manager.archive_old_logs(days_old=30)

    assert archived > 0


def test_search_logs(temp_log_env):
    """Test searching logs."""
    manager = LogManager(log_dir=temp_log_env)

    # Create test logs
    (Path(temp_log_env) / "app.log").write_text(
        "Error occurred\nWarning message\nError again"
    )
    (Path(temp_log_env) / "debug.log").write_text(
        "Debug info\nError in debug"
    )

    results = manager.search_logs("Error", case_sensitive=False)

    assert len(results) >= 1
    assert any("Error" in line for lines in results.values()
               for line in lines)


def test_search_logs_case_sensitive(temp_log_env):
    """Test case-sensitive log search."""
    manager = LogManager(log_dir=temp_log_env)

    (Path(temp_log_env) / "app.log").write_text("ERROR\nerror\nError")

    results = manager.search_logs("ERROR", case_sensitive=True)

    assert "app.log" in results
    # Should only find uppercase ERROR
    assert len(results["app.log"]) == 1


def test_export_logs(temp_log_env):
    """Test exporting logs."""
    manager = LogManager(log_dir=temp_log_env)

    # Create test logs
    (Path(temp_log_env) / "app.log").write_text("log content 1")
    (Path(temp_log_env) / "error.log").write_text("log content 2")

    output_file = Path(temp_log_env) / "export.tar"
    result = manager.export_logs(str(output_file), compress=True)

    assert result is True
    # The method adds .tar.gz suffix
    assert (Path(temp_log_env) / "export.tar.gz").exists()


def test_export_logs_uncompressed(temp_log_env):
    """Test exporting logs without compression."""
    manager = LogManager(log_dir=temp_log_env)

    (Path(temp_log_env) / "app.log").write_text("log content")

    output_file = Path(temp_log_env) / "export.txt"
    result = manager.export_logs(str(output_file), compress=False)

    assert result is True
    assert output_file.exists()
    assert "log content" in output_file.read_text()


def test_get_log_stats(temp_log_env):
    """Test getting log statistics."""
    manager = LogManager(log_dir=temp_log_env)

    # Create test logs
    (Path(temp_log_env) / "app.log").write_text("x" * 1000)
    (Path(temp_log_env) / "error.log").write_text("y" * 2000)

    stats = manager.get_log_stats()

    assert stats["total_files"] == 2
    assert stats["total_size_bytes"] >= 3000


def test_get_log_stats_empty(temp_log_env):
    """Test getting stats with no logs."""
    manager = LogManager(log_dir=temp_log_env)

    stats = manager.get_log_stats()

    assert stats["total_files"] == 0
    assert stats["total_size_bytes"] == 0


def test_cleanup_logs(temp_log_env):
    """Test log cleanup."""
    import time
    
    manager = LogManager(log_dir=temp_log_env)

    # Create multiple logs with different timestamps
    for i in range(10):
        log_file = Path(temp_log_env) / f"log_{i}.log"
        log_file.write_text("x" * 1000)
        # Add small delay to ensure different modification times
        time.sleep(0.01)

    deleted = manager.cleanup_logs(max_total_size_mb=0.001, keep_files=2)

    assert deleted > 0


def test_set_log_level():
    """Test setting log level."""
    manager = LogManager()

    result = manager.set_log_level("test_logger", "DEBUG")

    assert result is True


def test_get_log_manager_singleton():
    """Test singleton log manager."""
    manager1 = get_log_manager()
    manager2 = get_log_manager()

    assert manager1 is manager2
    assert isinstance(manager1, LogManager)
