#!/usr/bin/env python3
"""
PostToolUse hook for bluera-knowledge plugin.

Fires after Claude reads/greps in dependency directories,
reminding to consider using BK for similar future queries.

Note: If pretooluse blocked the read (library was indexed), this hook won't fire.
This hook only fires for non-indexed libraries that were allowed through.
"""

import json
import os
import re
import sys
from typing import TypedDict

# Shared store helpers
sys.path.insert(
    0, os.path.join(os.environ.get("CLAUDE_PLUGIN_ROOT", "."), "hooks", "lib")
)
from store_summary import format_store_names, is_store_match, load_stores


class ToolInputDict(TypedDict, total=False):
    """Tool input structure from hook."""

    path: str  # For Grep
    file_path: str  # For Read


# Dependency path patterns with boundary markers to avoid false positives
DEPENDENCY_PATTERNS = (
    "/node_modules/",
    "/vendor/",
    "/site-packages/",
    "/.venv/",
    "/venv/",
    "/bower_components/",
    "/.npm/",
    "/.cargo/registry/",
    "/go/pkg/mod/",
)


def is_dependency_path(path: str) -> bool:
    """Return True only if path is inside a dependency directory."""
    normalized = "/" + path.replace("\\", "/").lower()
    return any(pattern in normalized for pattern in DEPENDENCY_PATTERNS)


def extract_library_name(path: str) -> str | None:
    """Extract library name from dependency path."""
    # node_modules/package-name/... or node_modules/@scope/package/...
    match = re.search(r"node_modules/(@[^/]+/[^/]+|[^/]+)", path)
    if match:
        return match.group(1)

    # site-packages/package_name/...
    match = re.search(r"site-packages/([^/]+)", path)
    if match:
        return match.group(1)

    # vendor/package/...
    match = re.search(r"vendor/([^/]+)", path)
    if match:
        return match.group(1)

    # .cargo/registry/.../package-name-version/...
    match = re.search(r"\.cargo/registry/[^/]+/([^/]+)-\d", path)
    if match:
        return match.group(1)

    # go/pkg/mod/package@version/...
    match = re.search(r"go/pkg/mod/([^@]+)@", path)
    if match:
        return match.group(1)

    return None


def check_tool(
    tool_name: str, tool_input: ToolInputDict
) -> tuple[str | None, str | None]:
    """Check if tool targeted library code. Returns (action, library_name)."""
    if tool_name == "Grep":
        path = tool_input.get("path", "")
    elif tool_name == "Read":
        path = tool_input.get("file_path", "")
    else:
        return None, None

    if not path or not is_dependency_path(path):
        return None, None

    lib_name = extract_library_name(path)
    action = f"read `{path}`" if tool_name == "Read" else f"grepped in `{path}`"
    return action, lib_name


def main() -> int:
    try:
        stdin_data = sys.stdin.read()
        if not stdin_data.strip():
            return 0
        hook_input = json.loads(stdin_data)

        tool_name = hook_input.get("tool_name", "")
        tool_input = hook_input.get("tool_input", {})

        action, lib_name = check_tool(tool_name, tool_input)
        if not action:
            return 0

        # Matched-store-first: check if the library is already indexed
        stores = load_stores()
        matched_store = is_store_match(lib_name, stores) if lib_name else None

        if matched_store:
            # Library IS indexed — redirect to BK search
            reminder = (
                f"**{matched_store}** is already indexed in BK. "
                f"Use mcp__bluera-knowledge__search(query='...', stores=['{matched_store}']) "
                f"instead of reading raw files."
            )
        else:
            # Library NOT indexed — generic reminder + show what IS indexed
            lib_hint = f" ({lib_name})" if lib_name else ""
            add_hint = (
                f"Consider: /bluera-knowledge:add-repo {lib_name}" if lib_name else ""
            )
            catalog = format_store_names(stores, cap=5) if stores else ""
            indexed_hint = f" Currently indexed: {catalog}." if catalog else ""
            reminder = (
                f"You just {action}{lib_hint}. "
                f"For future queries, use BK search.{indexed_hint} {add_hint}"
            )

        output = {
            "hookSpecificOutput": {
                "hookEventName": "PostToolUse",
                "additionalContext": reminder.strip(),
            }
        }
        print(json.dumps(output))
        return 0

    except Exception:
        return 0  # Never fail on errors


if __name__ == "__main__":
    raise SystemExit(main())
