"""
castor.init_config — Generate a minimal starter robot.rcan.yaml.

Used by the Docker entrypoint and `castor init` CLI command to scaffold
a valid config without requiring an interactive TTY.

Usage:
    python -m castor.init_config [--output robot.rcan.yaml] [--name my-robot]
    castor init [--output robot.rcan.yaml] [--name my-robot]
"""

from __future__ import annotations

import argparse
import socket
import sys
from pathlib import Path

try:
    import yaml  # noqa: F401
except ImportError:
    import subprocess

    subprocess.check_call([sys.executable, "-m", "pip", "install", "pyyaml"])

MINIMAL_CONFIG_TEMPLATE = """\
# OpenCastor Robot Configuration
# Generated by `castor init` — edit this file to configure your robot.
# Full schema: https://opencastor.com/docs/config/
# All fields: config/rcan.schema.json

rcan_version: "1.3"

metadata:
  robot_name: "{robot_name}"
  description: "My OpenCastor robot"
  manufacturer: "custom"
  model: "custom-v1"
  version: "v1"
  robot_uuid: "{robot_uuid}"
  # rrn: ""  # Uncomment after registering at robotregistryfoundation.org

# AI provider — pick one and add API key to .env
# Docs: https://opencastor.com/docs/providers/
agent:
  provider: "mock"           # Change to: anthropic, google, openai, etc.
  model: "mock-model"        # Change to: claude-sonnet-4-5, gemini-2.5-flash, etc.
  system_prompt: "You are a helpful robot assistant."

# Hardware drivers — uncomment what you have
# Docs: https://opencastor.com/docs/hardware/
drivers: []
# drivers:
# - id: wheels
#   protocol: pca9685       # I2C motor controller
# - id: arm
#   protocol: dynamixel     # Dynamixel servo bus
# - id: camera
#   protocol: oak_d         # OAK-D depth camera

# Safety limits
safety:
  max_linear_velocity_ms: 0.5
  max_angular_velocity_rads: 1.0
  estop_enabled: true

# RCAN protocol settings
rcan_protocol:
  enabled: true
  capabilities: []           # Auto-detected from drivers above
  # registry_url: "https://robotregistryfoundation.org/api/v1"
"""


def generate_config(robot_name: str | None = None) -> str:
    """Generate a minimal valid robot.rcan.yaml config string.

    Args:
        robot_name: Name for the robot. Defaults to hostname.

    Returns:
        YAML config string.
    """
    import uuid

    if robot_name is None:
        robot_name = socket.gethostname().replace("-", "_")

    return MINIMAL_CONFIG_TEMPLATE.format(
        robot_name=robot_name,
        robot_uuid=str(uuid.uuid4())[:8],
    )


def write_config(
    output_path: str,
    robot_name: str | None = None,
    overwrite: bool = False,
) -> str:
    """Write a minimal config to disk.

    Args:
        output_path: Path to write the config file.
        robot_name: Optional robot name override.
        overwrite: If True, overwrite existing file. Defaults to False.

    Returns:
        Absolute path to the written config file.

    Raises:
        FileExistsError: If file already exists and overwrite=False.
    """
    path = Path(output_path).expanduser().resolve()
    path.parent.mkdir(parents=True, exist_ok=True)

    if path.exists() and not overwrite:
        raise FileExistsError(
            f"Config already exists: {path}\n"
            f"Use --overwrite to replace it, or --config to specify a different path."
        )

    config_str = generate_config(robot_name=robot_name)
    path.write_text(config_str, encoding="utf-8")
    return str(path)


def main() -> None:
    """CLI entry point: python -m castor.init_config or castor init."""
    parser = argparse.ArgumentParser(
        description="Generate a minimal starter robot.rcan.yaml config.",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  castor init                              # Creates robot.rcan.yaml in current dir
  castor init --output /app/config/robot.rcan.yaml
  castor init --name my-arm-robot
  castor init --overwrite                  # Replace existing config
        """,
    )
    parser.add_argument(
        "--output",
        "-o",
        default="robot.rcan.yaml",
        help="Output path for the config file (default: robot.rcan.yaml)",
    )
    parser.add_argument(
        "--name",
        "-n",
        default=None,
        help="Robot name (default: hostname)",
    )
    parser.add_argument(
        "--overwrite",
        action="store_true",
        help="Overwrite existing config file",
    )
    parser.add_argument(
        "--print",
        action="store_true",
        help="Print config to stdout instead of writing to file",
    )
    args = parser.parse_args()

    if args.print:
        print(generate_config(robot_name=args.name))
        return

    try:
        path = write_config(args.output, robot_name=args.name, overwrite=args.overwrite)
        print(f"✓ Config written to: {path}")
        print("\nNext steps:")
        print(f"  1. Edit the config:  nano {path}")
        print("  2. Add your AI key to .env (ANTHROPIC_API_KEY, GOOGLE_API_KEY, etc.)")
        print(f"  3. Run your robot:   castor run --config {path}")
        print("\nFull docs: https://opencastor.com/docs/")
    except FileExistsError as e:
        print(f"✗ {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
