"""REVIEW.md constants and shared helpers.

PRD-FIX-066 FR05: Extracted from _sync.py to reduce its line count.
The ``generate_review_md`` orchestrator remains in ``_sync.py`` because
existing tests patch ``_sync.recall_learnings`` and ``_sync.tempfile``
at the module level. Moving it would break backward-compatible patch paths.

Shared helpers:
- ``_sanitize_summary`` — used by both REVIEW.md and AGENTS.md generation.
- ``_get_repo_root`` — detects git root for REVIEW.md placement.
- ``recall_learnings`` — fail-safe memory adapter wrapper.
"""

from __future__ import annotations

import re
import subprocess
from pathlib import Path

import structlog

from trw_mcp.exceptions import StateError

logger = structlog.get_logger(__name__)

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------

_REVIEW_TAGS = ["gotcha", "bug", "security", "type-safety", "testing", "pattern"]
_REVIEW_MAX_LEARNINGS = 20
_REVIEW_MIN_IMPACT = 0.7

_REVIEW_TEMPLATE = """\
# REVIEW.md — Auto-generated by TRW
<!-- TRW:AUTO-GENERATED — manual edits will be overwritten on next trw_deliver() -->

## Always check
- New public functions without corresponding tests
- `Any` type annotations or bare `dict` usage
- `# type: ignore` comments without justification
- New API endpoints without input validation
- Functions not called from any other module (orphan detection)

## TRW Learnings (auto-injected)
{learning_entries}

## Skip
- docs/sprint-*/runs/** (generated sprint artifacts)
- .trw/** (framework persistence layer)
- **/scratch/** (agent working directories)
"""


# ---------------------------------------------------------------------------
# Shared helpers
# ---------------------------------------------------------------------------


def _sanitize_summary(summary: str) -> str:
    """Strip markdown links, HTML tags, and bare URLs from summary."""
    # [text](url) -> text
    text = re.sub(r"\[([^\]]+)\]\([^)]+\)", r"\1", summary)
    # <tag> -> ""
    text = re.sub(r"<[^>]+>", "", text)
    # Bare URLs
    text = re.sub(r"https?://\S+", "", text)
    return text.strip()


def _get_repo_root() -> Path | None:
    """Detect git repository root via ``git rev-parse``."""
    try:
        result = subprocess.run(
            ["git", "rev-parse", "--show-toplevel"],  # noqa: S607 — git is a well-known VCS tool; all args are static literals, no user input
            capture_output=True,
            text=True,
            timeout=5,
        )
        if result.returncode == 0:
            return Path(result.stdout.strip())
    except Exception:  # justified: fail-open, git root detection failure is non-fatal
        logger.debug("git_repo_root_detection_skipped", exc_info=True)
    return None


def recall_learnings(
    trw_dir: Path,
    *,
    tags: list[str] | None = None,
    min_impact: float = 0.0,
    status: str | None = None,
    max_results: int = 25,
) -> list[dict[str, object]]:
    """Query learnings from the memory adapter.

    Wraps ``memory_adapter.recall_learnings`` with a fail-safe fallback.
    """
    try:
        from trw_mcp.state.memory_adapter import recall_learnings as _recall

        return _recall(
            trw_dir,
            "*",
            tags=tags,
            min_impact=min_impact,
            status=status,
            max_results=max_results,
        )
    except (ImportError, OSError, ValueError, StateError):
        return []
