"""Shared utilities for neo-cortex."""

import importlib.resources
import json
import os


def load_mbel_grammar() -> str:
    """Load MBEL grammar from package data.

    Primary: importlib.resources (works with wheel/uvx installs).
    Fallback: relative to source tree (editable installs).
    """
    try:
        return importlib.resources.files("neo_cortex").joinpath("mbel.md").read_text(encoding="utf-8").strip()
    except Exception:
        pass
    pkg_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    mbel_path = os.path.join(pkg_dir, "mbel.md")
    try:
        with open(mbel_path, "r", encoding="utf-8") as f:
            return f.read().strip()
    except FileNotFoundError:
        return "(MBEL grammar not found)"


def read_mcp_env(var_name: str, search_from: str = "") -> str | None:
    """Read an env var from .mcp.json — searches cwd and parent directories."""
    search_dirs = set()
    for start in [search_from, os.getcwd()]:
        if not start:
            continue
        d = os.path.abspath(start)
        for _ in range(10):
            search_dirs.add(d)
            parent = os.path.dirname(d)
            if parent == d:
                break
            d = parent
    for d in search_dirs:
        candidate = os.path.join(d, ".mcp.json")
        if os.path.exists(candidate):
            try:
                with open(candidate, encoding="utf-8") as f:
                    data = json.load(f)
                for server in data.get("mcpServers", {}).values():
                    env = server.get("env", {})
                    if var_name in env:
                        return env[var_name]
            except Exception:
                pass
    return None


def find_project_root(search_from: str = "") -> str | None:
    """Walk up from search_from/cwd to find directory containing .mcp.json."""
    for start in [search_from, os.getcwd()]:
        if not start:
            continue
        d = os.path.abspath(start)
        for _ in range(10):
            if os.path.exists(os.path.join(d, ".mcp.json")):
                return d
            parent = os.path.dirname(d)
            if parent == d:
                break
            d = parent
    return None


def discover_data_dir(explicit: str | None = None, hook_cwd: str = "") -> str:
    """Find cortex data directory. Used by stop-hook, timeline, and config.

    Order: explicit arg → CORTEX_DATA_DIR env → .mcp.json env var → .mcp.json directory → hook cwd → process cwd.
    """
    return (explicit
            or os.environ.get("CORTEX_DATA_DIR")
            or read_mcp_env("CORTEX_DATA_DIR", hook_cwd)
            or find_project_root(hook_cwd)
            or hook_cwd
            or os.getcwd())
