"""
Paginated log reader tool for Armorer agents.

Stores a full error log in memory and serves batches of lines on demand,
allowing the repair agent to navigate through long logs without truncation.
"""

from armorer.agent_sdk import tool

# ── In-memory log store ──────────────────────────────────────────────────────

_log_store: dict[str, list[str]] = {}
_log_counter: int = 0


def store_log(content: str) -> str:
    """Store a log and return its session ID for later retrieval.

    Called internally by the installer before invoking the repair agent.
    """
    global _log_counter
    _log_counter += 1
    session_id = f"log_{_log_counter}"
    _log_store[session_id] = content.splitlines()
    return session_id


def get_log_summary(session_id: str, head: int = 40, tail: int = 40) -> str:
    """Return a head + tail summary of the stored log for the initial prompt.

    Shows the first *head* lines and last *tail* lines with a gap indicator.
    """
    lines = _log_store.get(session_id, [])
    total = len(lines)

    if total <= head + tail:
        return "\n".join(lines)

    head_block = "\n".join(lines[:head])
    tail_block = "\n".join(lines[-tail:])
    skipped = total - head - tail

    return (
        f"{head_block}\n"
        f"\n... [{skipped} lines hidden — use read_logs tool to navigate] ...\n\n"
        f"{tail_block}"
    )


def clear_log(session_id: str) -> None:
    """Remove a log from the store after the repair session ends."""
    _log_store.pop(session_id, None)


# ── Agent-facing tool ────────────────────────────────────────────────────────


def _read_logs_impl(session_id: str, start_line: int = 1, num_lines: int = 50) -> str:
    """Core implementation for log reading, callable from tests."""
    lines = _log_store.get(session_id)
    if lines is None:
        return f"Error: No log found for session '{session_id}'."

    total = len(lines)
    num_lines = min(num_lines, 200)

    # Convert to 0-indexed
    start_idx = max(0, start_line - 1)
    end_idx = min(start_idx + num_lines, total)

    if start_idx >= total:
        return f"Error: start_line {start_line} exceeds total lines ({total})."

    batch = lines[start_idx:end_idx]
    header = f"[Lines {start_idx + 1}–{end_idx} of {total}]"

    return f"{header}\n" + "\n".join(batch)


@tool(category="debug", verification_level="log_read", safe_for_retrieval=True)
def read_logs(session_id: str, start_line: int = 1, num_lines: int = 50) -> str:
    """
    Read a batch of lines from the stored error log.

    The full log is stored in memory so you can navigate through it
    without truncation. Use this to investigate specific sections when
    the head+tail summary in the prompt isn't enough.

    Args:
        session_id: The log session ID (provided in the prompt).
        start_line: Line number to start reading from (1-indexed).
        num_lines:  Number of lines to return (default 50, max 200).
    """
    return _read_logs_impl(session_id, start_line, num_lines)
