"""Lightweight middleware config loader for Claude Code hooks.

Self-contained module that only depends on stdlib + yaml.
Keeps hooks decoupled from the MCP server package structure.

Usage in hooks:
    from middleware_config import load_middleware_config
    config = load_middleware_config()
    if config["enabled"] and config["cache"]["enabled"]:
        # ... cache logic
"""

import os
import sys
from pathlib import Path

try:
    import yaml
except ImportError:
    yaml = None


# Default configuration (matches MiddlewareConfig dataclass defaults)
_DEFAULTS = {
    "enabled": True,
    "verbose": False,
    "cache": {
        "enabled": True,
        "verbose": False,
        "ttl": {
            "Read": 300,
            "Grep": 300,
            "Glob": 600,
            "WebFetch": 1800,
        },
        "max_cached_response_size": 4000,
        "whitelist": ["Read", "Grep", "Glob", "WebFetch"],
    },
}


def _deep_merge(base: dict, override: dict) -> dict:
    """Deep-merge override into base."""
    result = base.copy()
    for key, value in override.items():
        if key in result and isinstance(result[key], dict) and isinstance(value, dict):
            result[key] = _deep_merge(result[key], value)
        else:
            result[key] = value
    return result


def _load_yaml(path: Path) -> dict:
    """Load YAML file, returning empty dict on any error."""
    if yaml is None:
        return {}
    if not path.exists():
        return {}
    try:
        with open(path, "r") as f:
            data = yaml.safe_load(f)
            return data if isinstance(data, dict) else {}
    except Exception as e:
        print(f"[middleware] Warning: {path}: {e}", file=sys.stderr)
        return {}


def load_middleware_config(project_path: str = None) -> dict:
    """Load middleware config as a plain dict with layered merging.

    Priority: project > global > defaults.
    Always returns a valid config dict (fail-open).

    Args:
        project_path: Project directory. Defaults to CLAUDE_PROJECT_DIR or cwd.

    Returns:
        Config dict with all keys guaranteed present.
    """
    if project_path is None:
        project_path = os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())

    import copy
    config = copy.deepcopy(_DEFAULTS)

    # Load and merge global
    global_data = _load_yaml(Path.home() / ".omni-cortex" / "middleware.yaml")
    if global_data:
        mw = global_data.get("middleware", global_data)
        config = _deep_merge(config, mw)

    # Load and merge project
    project_data = _load_yaml(Path(project_path) / ".omni-cortex" / "middleware.yaml")
    if project_data:
        mw = project_data.get("middleware", project_data)
        config = _deep_merge(config, mw)

    return config
