"""Default filter configurations for CLI output processing.

This module provides pre-configured filter pipelines for common use cases.
New filter patterns can be added here without modifying the core filter logic.

To add a new filter pattern:
    1. Add a constant for the pattern
    2. Add it to the appropriate pipeline
    3. No other code changes needed
"""

from __future__ import annotations

import re

from .filters import (
    BlockRemoveFilter,
    FilterPipeline,
    LineFilter,
    LinePrefixStripFilter,
    RegexRemoveFilter,
)

# =============================================================================
# Regex Patterns
# =============================================================================

# System reminder tags (Claude Code internal instructions)
SYSTEM_REMINDER_PATTERN = re.compile(
    r"<system-reminder>.*?</system-reminder>",
    re.DOTALL,
)

# Usage metadata blocks
USAGE_BLOCK_PATTERN = re.compile(
    r"<usage>.*?</usage>",
    re.DOTALL,
)

# Line number prefixes from file read output (e.g., "  42→")
LINE_NUMBER_PREFIX_PATTERN = re.compile(r"^\s*\d+→")


# =============================================================================
# Line-based Filters
# =============================================================================

# Metadata line prefixes that should be filtered from user-facing output
METADATA_LINE_PREFIXES: frozenset[str] = frozenset(
    {
        "agentId:",
        "<usage>",
        "tool_uses:",
        "duration_ms:",
        "total_tokens:",
        "input_tokens:",
        "output_tokens:",
    }
)

# Hardcoded hints from Claude Code that leak into output
METADATA_HINTS: frozenset[str] = frozenset(
    {
        "Whenever you read a file",
        "(for resuming to continue this agent's work if needed)",
    }
)


def is_not_metadata_line(line: str) -> bool:
    """Predicate: Returns True if line should be KEPT (not metadata).

    Filters lines that start with known metadata prefixes.
    """
    stripped = line.strip()
    return not any(stripped.startswith(prefix) for prefix in METADATA_LINE_PREFIXES)


def is_not_metadata_hint(line: str) -> bool:
    """Predicate: Returns True if line should be KEPT (not a hint).

    Filters lines containing hardcoded Claude Code hints.
    """
    return not any(hint in line for hint in METADATA_HINTS)


# =============================================================================
# Pre-configured Pipelines
# =============================================================================

CLI_TOOL_RESPONSE_FILTERS = FilterPipeline(
    [
        # First pass: Remove complete blocks via regex
        RegexRemoveFilter(SYSTEM_REMINDER_PATTERN),
        RegexRemoveFilter(USAGE_BLOCK_PATTERN),
        # Second pass: State machine for partial/malformed blocks
        BlockRemoveFilter("<system-reminder>", "</system-reminder>"),
        BlockRemoveFilter("<usage>", "</usage>"),
        # Third pass: Line-level filtering
        LineFilter(is_not_metadata_line),
        LineFilter(is_not_metadata_hint),
        # Fourth pass: Strip line number prefixes
        LinePrefixStripFilter(LINE_NUMBER_PREFIX_PATTERN),
    ]
)
"""Default filter pipeline for CLI tool response output.

This pipeline:
1. Removes <system-reminder> blocks (regex + state machine for robustness)
2. Removes <usage> metadata blocks
3. Filters lines starting with metadata prefixes (agentId:, tool_uses:, etc.)
4. Filters lines containing Claude Code hints
5. Strips line number prefixes from file read output
"""
