"""Configuration management for rubberduck-index.

Reads/writes .rubberduck/config.json in the project root.
"""

import json
import os
from pathlib import Path
from typing import Any, Dict, List, Optional


CONFIG_DIR = ".rubberduck"
CONFIG_FILE = "config.json"
IGNORE_FILE = "ignore"

DEFAULT_SERVER = "https://semantic.rubberduck.com"

DEFAULT_CONFIG = {
    "server": DEFAULT_SERVER,
    "project": "",
    "token": "",
    "include": ["**/*.py"],
    "exclude_defaults": True,
    "max_file_size": 50_000_000,
    "watch_debounce_ms": 500,
}

# Always excluded regardless of config
ALWAYS_EXCLUDE = [
    "__pycache__",
    ".git",
    ".hg",
    ".svn",
    "node_modules",
    ".venv",
    "venv",
    ".env",
    ".tox",
    ".mypy_cache",
    ".pytest_cache",
    ".eggs",
    "*.egg-info",
    "dist",
    "build",
    ".DS_Store",
]


def find_project_root(start: Optional[str] = None) -> Optional[Path]:
    """Walk up from start dir to find a directory containing .rubberduck/config.json."""
    current = Path(start or os.getcwd()).resolve()
    for _ in range(50):  # safety limit
        if (current / CONFIG_DIR / CONFIG_FILE).exists():
            return current
        parent = current.parent
        if parent == current:
            break
        current = parent
    return None


def load_config(project_root: Optional[Path] = None) -> Dict[str, Any]:
    """Load config from .rubberduck/config.json. Returns empty dict if not found."""
    if project_root is None:
        project_root = find_project_root()
    if project_root is None:
        return {}

    config_path = project_root / CONFIG_DIR / CONFIG_FILE
    if not config_path.exists():
        return {}

    try:
        return json.loads(config_path.read_text())
    except (json.JSONDecodeError, OSError):
        return {}


def save_config(project_root: Path, config: Dict[str, Any]) -> Path:
    """Save config to .rubberduck/config.json. Returns path to config file."""
    config_dir = project_root / CONFIG_DIR
    config_dir.mkdir(parents=True, exist_ok=True)

    config_path = config_dir / CONFIG_FILE
    config_path.write_text(json.dumps(config, indent=2) + "\n")
    return config_path


def load_ignore_patterns(project_root: Path) -> List[str]:
    """Load extra ignore patterns from .rubberduck/ignore."""
    ignore_path = project_root / CONFIG_DIR / IGNORE_FILE
    if not ignore_path.exists():
        return []

    patterns = []
    for line in ignore_path.read_text().splitlines():
        line = line.strip()
        if line and not line.startswith("#"):
            patterns.append(line)
    return patterns


def load_gitignore_patterns(project_root: Path) -> List[str]:
    """Load .gitignore patterns from the project root."""
    gitignore = project_root / ".gitignore"
    if not gitignore.exists():
        return []

    patterns = []
    for line in gitignore.read_text().splitlines():
        line = line.strip()
        if line and not line.startswith("#"):
            patterns.append(line)
    return patterns
