import pytest
import os
import shutil
from datetime import datetime, timedelta
from src.log_registry import LogRegistry
from src.log_pruner import LogPruner

class TestLogPruningHeuristic:
 @pytest.fixture
 def temp_logs_dir(self, tmp_path):
  # Create a structure: project_root/logs/sessions
  project_root = tmp_path
  logs_dir = project_root / "logs" / "sessions"
  logs_dir.mkdir(parents=True)
  return logs_dir

 @pytest.fixture
 def registry_path(self, temp_logs_dir):
  return temp_logs_dir / "log_registry.toml"

 def test_get_old_non_whitelisted_sessions_includes_empty_sessions(self, registry_path):
  registry = LogRegistry(str(registry_path))
  
  # 1. Old non-whitelisted session
  old_time = datetime.now() - timedelta(days=2)
  registry.register_session("old_session", "logs/old_session", old_time)
  
  # 2. New session with 0 messages (empty)
  new_time = datetime.now()
  registry.register_session("empty_session", "logs/empty_session", new_time)
  registry.update_session_metadata("empty_session", message_count=0, errors=0, size_kb=0, whitelisted=False, reason="")
  
  # 3. New session with messages (not empty)
  registry.register_session("active_session", "logs/active_session", new_time)
  registry.update_session_metadata("active_session", message_count=5, errors=0, size_kb=10, whitelisted=False, reason="")
  
  # 4. Whitelisted session
  registry.register_session("starred_session", "logs/starred_session", old_time)
  registry.update_session_metadata("starred_session", message_count=0, errors=0, size_kb=0, whitelisted=True, reason="starred")

  cutoff = datetime.now() - timedelta(days=1)
  sessions = registry.get_old_non_whitelisted_sessions(cutoff)
  
  session_ids = [s['session_id'] for s in sessions]
  assert "old_session" in session_ids
  assert "empty_session" in session_ids
  assert "active_session" not in session_ids
  assert "starred_session" not in session_ids

 def test_get_old_non_whitelisted_sessions_includes_sessions_without_metadata(self, registry_path):
  registry = LogRegistry(str(registry_path))
  new_time = datetime.now()
  # Session registered but update_auto_whitelist_status not called yet
  registry.register_session("no_meta_session", "logs/no_meta_session", new_time)
  
  cutoff = datetime.now() - timedelta(days=1)
  sessions = registry.get_old_non_whitelisted_sessions(cutoff)
  
  session_ids = [s['session_id'] for s in sessions]
  assert "no_meta_session" in session_ids

 def test_prune_handles_relative_paths_starting_with_logs(self, temp_logs_dir, registry_path):
  # Project structure: project_root/logs/sessions
  project_root = temp_logs_dir.parent.parent
  
  # Create a session dir in project_root/logs/session_1
  session_id = "session_1"
  session_rel_path = os.path.join("logs", session_id)
  session_abs_path = project_root / session_rel_path
  session_abs_path.mkdir(parents=True)
  (session_abs_path / "comms.log").write_text("empty")

  registry = LogRegistry(str(registry_path))
  registry.register_session(session_id, session_rel_path, datetime.now())
  # No metadata = empty
  
  pruner = LogPruner(registry, str(temp_logs_dir))
  pruner.prune(max_age_days=1, min_size_kb=10)
  
  assert not session_abs_path.exists()
  assert session_id not in registry.data

 def test_prune_removes_empty_sessions_regardless_of_age(self, temp_logs_dir, registry_path):
  # Mock project root resolution in LogPruner
  project_root = temp_logs_dir.parent.parent
  
  session_id = "new_empty"
  session_rel_path = os.path.join("logs", session_id)
  session_abs_path = project_root / session_rel_path
  session_abs_path.mkdir(parents=True)

  registry = LogRegistry(str(registry_path))
  registry.register_session(session_id, session_rel_path, datetime.now())
  registry.update_session_metadata(session_id, message_count=0, errors=0, size_kb=0, whitelisted=False, reason="")
  
  pruner = LogPruner(registry, str(temp_logs_dir))
  # max_age_days=10, but should still prune because it's empty
  pruner.prune(max_age_days=10, min_size_kb=10)
  
  assert not session_abs_path.exists()
  assert session_id not in registry.data

 def test_prune_removes_sessions_without_metadata_regardless_of_age(self, temp_logs_dir, registry_path):
  project_root = temp_logs_dir.parent.parent
  
  session_id = "new_no_meta"
  session_rel_path = os.path.join("logs", session_id)
  session_abs_path = project_root / session_rel_path
  session_abs_path.mkdir(parents=True)

  registry = LogRegistry(str(registry_path))
  registry.register_session(session_id, session_rel_path, datetime.now())
  # No metadata update
  
  pruner = LogPruner(registry, str(temp_logs_dir))
  pruner.prune(max_age_days=10, min_size_kb=10)
  
  assert not session_abs_path.exists()
  assert session_id not in registry.data
