"""
Logger for RLM iterations.

Writes RLMIteration data to JSON-lines files for analysis and debugging.

Security Features (SEC-012):
- Path traversal prevention using pathlib
- Directory validation
"""

import json
import uuid
from datetime import datetime
from pathlib import Path
from typing import Optional

from groknroll.core.types import RLMIteration, RLMMetadata


def _validate_log_directory(log_dir: Path, base_dir: Optional[Path] = None) -> Path:
    """
    Validate and resolve the log directory path.

    SEC-012: Path traversal prevention.

    Args:
        log_dir: The log directory path
        base_dir: Optional base directory to restrict paths to

    Returns:
        Resolved and validated Path

    Raises:
        ValueError: If path traversal is detected
    """
    resolved = log_dir.resolve()

    # Check for path traversal if base_dir is specified
    if base_dir is not None:
        base_resolved = base_dir.resolve()
        try:
            resolved.relative_to(base_resolved)
        except ValueError:
            raise ValueError(
                f"Path traversal detected: '{log_dir}' resolves outside of base directory "
                f"'{base_dir}'. This is not allowed for security reasons."
            )

    return resolved


class RLMLogger:
    """Logger that writes RLMIteration data to a JSON-lines file."""

    def __init__(self, log_dir: str, file_name: str = "rlm", base_dir: Optional[str] = None):
        """
        Initialize RLMLogger with path validation.

        Args:
            log_dir: Directory for log files
            file_name: Base name for log files
            base_dir: Optional base directory to restrict log paths

        Raises:
            ValueError: If log_dir is outside base_dir (path traversal)
        """
        # SEC-012: Use pathlib for safer path handling
        log_path = Path(log_dir)
        base_path = Path(base_dir) if base_dir else None

        # Validate path
        validated_path = _validate_log_directory(log_path, base_path)

        self.log_dir = validated_path
        self.log_dir.mkdir(parents=True, exist_ok=True)

        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        run_id = str(uuid.uuid4())[:8]

        # SEC-012: Sanitize file_name to prevent path injection
        safe_file_name = "".join(c for c in file_name if c.isalnum() or c in "._-")
        if not safe_file_name:
            safe_file_name = "rlm"

        self.log_file_path = self.log_dir / f"{safe_file_name}_{timestamp}_{run_id}.jsonl"

        self._iteration_count = 0
        self._metadata_logged = False

    def log_metadata(self, metadata: RLMMetadata):
        """Log RLM metadata as the first entry in the file."""
        if self._metadata_logged:
            return

        entry = {
            "type": "metadata",
            "timestamp": datetime.now().isoformat(),
            **metadata.to_dict(),
        }

        with open(self.log_file_path, "a") as f:
            json.dump(entry, f)
            f.write("\n")

        self._metadata_logged = True

    def log(self, iteration: RLMIteration):
        """Log an RLMIteration to the file."""
        self._iteration_count += 1

        entry = {
            "type": "iteration",
            "iteration": self._iteration_count,
            "timestamp": datetime.now().isoformat(),
            **iteration.to_dict(),
        }

        with open(self.log_file_path, "a") as f:
            json.dump(entry, f)
            f.write("\n")

    @property
    def iteration_count(self) -> int:
        return self._iteration_count
