"""Configuration for the Neo Cortex server.

All configuration comes from environment variables, set via .mcp.json env block.
No ~/.accounts, no hardcoded paths, no system env vars.
"""

import os

__all__ = [
    "load_api_key",
    "CORTEX_DB_PATH", "COLLECTION_NAME", "MEMORY_INDEX_DB_PATH",
    "CONVERSATION_DB_PATH",
    "JINA_MODEL", "JINA_DIMENSIONS", "JINA_URL",
    "LLM_PROVIDER", "LLM_BASE_URL", "LLM_MODEL",
    "CLASSIFIER_PROVIDER", "DISTILLER_PROVIDER",
    "GROQ_MODEL", "GROQ_URL",
    "GEMINI_MODEL", "GEMINI_URL",
    "PROJECT_NAMES",
    "DIGESTOR_BUDGET", "DIGESTOR_BUDGET_MAX",
    "DIGESTOR_BUDGET_THRESHOLD",
    "CONSOLIDATION_SIMILARITY_THRESHOLD", "CONSOLIDATION_MAX_GROUP_SIZE",
]


_KEY_ENV_VARS = {
    "gemini": "GEMINI_API_KEY",
    "groq": "GROQ_API_KEY",
    "openai": "OPENAI_API_KEY",
    "anthropic": "ANTHROPIC_API_KEY",
    "xai": "XAI_API_KEY",
    "zai": "ZAI_API_KEY",
    "jina": "JINA_API_KEY",
}


def load_api_key(name: str) -> str:
    """Load an API key from environment variable.

    Keys are passed via .mcp.json env block:
        "env": { "JINA_API_KEY": "...", "GROQ_API_KEY": "...", "GEMINI_API_KEY": "..." }
    """
    env_var = _KEY_ENV_VARS.get(name, f"{name.upper()}_API_KEY")
    env_val = os.environ.get(env_var)
    if env_val:
        return env_val
    raise KeyError(f"Key '{name}' not found — set {env_var} in .mcp.json env block")


# Paths — all derivable from CORTEX_DATA_DIR
# Only override individual paths if you need non-standard layout
def _find_project_root() -> str:
    """Find project root by walking up to .mcp.json. Prevents sub-agents from creating cortex_db in subdirectories."""
    d = os.path.abspath(os.getcwd())
    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 os.getcwd()

_data_dir = os.environ.get("CORTEX_DATA_DIR") or _find_project_root()
_default_db = os.path.join(_data_dir, "cortex_db")

CORTEX_DB_PATH = os.environ.get("CORTEX_DB_PATH", _default_db)
COLLECTION_NAME = os.environ.get("CORTEX_COLLECTION", "conversations_v2")

# Memory index (SQLite + FTS5)
MEMORY_INDEX_DB_PATH = os.environ.get("MEMORY_INDEX_DB_PATH", os.path.join(CORTEX_DB_PATH, "memory_index.db"))

# Conversation log
CONVERSATION_DB_PATH = os.environ.get("CONVERSATION_DB_PATH", os.path.join(CORTEX_DB_PATH, "conversation_log.db"))

# Jina embeddings
JINA_MODEL = os.environ.get("JINA_MODEL", "jina-embeddings-v3")
JINA_DIMENSIONS = int(os.environ.get("JINA_DIMENSIONS", "1024"))
JINA_URL = "https://api.jina.ai/v1/embeddings"

# LLM provider (replaces CLASSIFIER_PROVIDER — backward compatible)
LLM_PROVIDER = os.environ.get("LLM_PROVIDER") or os.environ.get("CLASSIFIER_PROVIDER", "gemini")
CLASSIFIER_PROVIDER = LLM_PROVIDER  # backward compat alias

# Distiller provider (can differ from classifier — e.g. classifier=groq, distiller=gemini)
DISTILLER_PROVIDER = os.environ.get("DISTILLER_PROVIDER") or LLM_PROVIDER

# OpenAI-compatible / custom provider settings
LLM_BASE_URL = os.environ.get("LLM_BASE_URL", "")
LLM_MODEL = os.environ.get("LLM_MODEL", "")

# Groq (legacy — available if CLASSIFIER_PROVIDER=groq)
GROQ_MODEL = os.environ.get("GROQ_MODEL", "llama-3.3-70b-versatile")
GROQ_URL = "https://api.groq.com/openai/v1/chat/completions"

# Gemini (default for classifier + distiller)
GEMINI_MODEL = os.environ.get("GEMINI_MODEL", "gemini-2.5-flash")
GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta"

# Project names — auto-detected at startup, override with PROJECT_NAMES (comma-separated)
# Detection order: PROJECT_NAMES env → .gitmodules → subdirs with .git → directory basename
# Single project: PROJECT_NAMES="my-app"
# Multiple: PROJECT_NAMES="backend,frontend,shared"
def _detect_project_names() -> list[str]:
    """Auto-detect project names from env, gitmodules, or directory structure."""
    # 1. Explicit override
    explicit = os.environ.get("PROJECT_NAMES", "").strip()
    if explicit:
        return [p.strip() for p in explicit.split(",") if p.strip()]

    projects = set()
    # 2. Read .gitmodules if exists
    gitmodules = os.path.join(_data_dir, ".gitmodules")
    if os.path.exists(gitmodules):
        try:
            with open(gitmodules, encoding="utf-8") as f:
                for line in f:
                    line = line.strip()
                    if line.startswith("path"):
                        path = line.split("=", 1)[1].strip()
                        name = os.path.basename(path)
                        if not name.startswith("."):
                            projects.add(name)
        except Exception:
            pass

    # 3. Subdirectories with .git (standalone repos in workspace)
    if not projects:
        try:
            for name in os.listdir(_data_dir):
                sub = os.path.join(_data_dir, name)
                if os.path.isdir(sub) and os.path.exists(os.path.join(sub, ".git")):
                    projects.add(name)
        except Exception:
            pass

    # 4. Root directory first, then submodules/subdirs sorted
    root_name = os.path.basename(_data_dir)
    projects.discard(root_name)  # remove if already there, we'll prepend it
    result = sorted(projects)
    if root_name and not root_name.startswith("."):
        result.insert(0, root_name)
    return result if result else ["general"]

PROJECT_NAMES = _detect_project_names()

# Digestor batch sizing (tokens)
DIGESTOR_BUDGET = int(os.environ.get("DIGESTOR_BUDGET", "32000"))
DIGESTOR_BUDGET_MAX = int(os.environ.get("DIGESTOR_BUDGET_MAX", "32000"))
DIGESTOR_BUDGET_THRESHOLD = int(os.environ.get("DIGESTOR_BUDGET_THRESHOLD", "200"))


# Consolidation (phase 2 — merge similar memories during idle)
CONSOLIDATION_SIMILARITY_THRESHOLD = float(os.environ.get("CONSOLIDATION_SIMILARITY_THRESHOLD", "0.82"))
CONSOLIDATION_MAX_GROUP_SIZE = int(os.environ.get("CONSOLIDATION_MAX_GROUP_SIZE", "3"))
