#!/usr/bin/env python3
"""
Config Validator -- pre-deploy YAML validation for timmy-config sidecar.

Validates YAML syntax, required keys (model.default, model.provider,
toolsets), and provider names before deploy.sh writes to ~/.hermes/.

Usage:
    python3 bin/validate_config.py [path/to/config.yaml]
    python3 bin/validate_config.py --strict  (fail on warnings too)
"""
import json, os, sys, yaml
from pathlib import Path

REQUIRED = {
    "model": {"type": dict, "keys": {"default": str, "provider": str}},
    "toolsets": {"type": list},
}
ALLOWED_PROVIDERS = [
    "anthropic", "openai", "nous", "ollama", "openrouter", "openai-codex"
]

def validate(path):
    errors = []
    try:
        with open(path) as f:
            data = yaml.safe_load(f)
    except Exception as e:
        return [f"YAML parse error: {e}"]
    if not isinstance(data, dict):
        return [f"Expected mapping, got {type(data).__name__}"]

    for key, spec in REQUIRED.items():
        if key not in data:
            errors.append(f"Required key missing: {key}")
            continue
        if spec["type"] == dict and not isinstance(data[key], dict):
            errors.append(f"{key}: expected dict")
            continue
        if spec["type"] == list and not isinstance(data[key], list):
            errors.append(f"{key}: expected list")
            continue
        if "keys" in spec:
            for sub, sub_type in spec["keys"].items():
                if sub not in data[key]:
                    errors.append(f"{key}.{sub}: required")
                elif not isinstance(data[key][sub], sub_type):
                    errors.append(f"{key}.{sub}: expected {sub_type.__name__}")

    provider = data.get("model", {}).get("provider")
    if provider and provider not in ALLOWED_PROVIDERS:
        errors.append(f"model.provider: unknown provider '{provider}'")

    # Check JSON files
    for jf in ["channel_directory.json"]:
        jp = Path(path).parent / jf
        if jp.exists():
            try:
                json.loads(jp.read_text())
            except Exception as e:
                errors.append(f"{jf}: invalid JSON: {e}")

    return errors

def main():
    strict = "--strict" in sys.argv
    args = [a for a in sys.argv[1:] if not a.startswith("--")]
    path = args[0] if args else str(Path(__file__).parent.parent / "config.yaml")

    if not os.path.exists(path):
        print(f"ERROR: {path} not found")
        sys.exit(1)

    errs = validate(path)
    if errs:
        for e in errs:
            print(f"ERROR: {e}")
        print(f"Validation FAILED: {len(errs)} issue(s)")
        sys.exit(1)
    print(f"OK: {path} is valid")

if __name__ == "__main__":
    main()
