"""Command-line interface for Carve.

Provides the `carve` command with subcommands for running the MCP and HTTP servers.
"""

from __future__ import annotations

import argparse
import asyncio
import sys
from typing import NoReturn


def main(argv: list[str] | None = None) -> int | NoReturn:
    """Main entry point for the carve CLI.

    Args:
        argv: Command-line arguments (defaults to sys.argv[1:])

    Returns:
        Exit code
    """
    parser = argparse.ArgumentParser(
        prog="carve",
        description="Text Editor for AI Agents",
    )

    subparsers = parser.add_subparsers(dest="command", help="Available commands")

    # serve command
    serve_parser = subparsers.add_parser("serve", help="Run the Carve server")
    serve_parser.add_argument(
        "--mcp",
        action="store_true",
        help="Run MCP server on stdio",
    )
    serve_parser.add_argument(
        "--http",
        action="store_true",
        help="Run HTTP server",
    )
    serve_parser.add_argument(
        "--port",
        type=int,
        default=8080,
        help="Port for HTTP server (default: 8080)",
    )
    serve_parser.add_argument(
        "--host",
        type=str,
        default="127.0.0.1",
        help="Host for HTTP server (default: 127.0.0.1)",
    )
    serve_parser.add_argument(
        "--path",
        type=str,
        help="Source file or project directory to load on startup (also CARVE_WORKSPACE env var)",
    )
    serve_parser.add_argument(
        "--file",
        type=str,
        help="Source file to load on startup (alias for --path)",
    )
    serve_parser.add_argument(
        "--read-only",
        action="store_true",
        help="Block all mutations (navigation and search only)",
    )
    serve_parser.add_argument(
        "--no-create",
        action="store_true",
        help="Block creating new files while allowing code edits",
    )
    serve_parser.add_argument(
        "--no-delete",
        action="store_true",
        help="Block deleting file/directory nodes while allowing code edits",
    )
    serve_parser.add_argument(
        "--allow-custom-tools",
        action="store_true",
        help="Enable custom project tools defined in carvesettings.toml [tools]",
    )

    args = parser.parse_args(argv)

    if args.command == "serve":
        return _run_serve(args)
    else:
        parser.print_help()
        return 1


def _run_serve(args: argparse.Namespace) -> int | NoReturn:
    """Run the serve command.

    Args:
        args: Parsed arguments

    Returns:
        Exit code
    """
    from pathlib import Path

    from carve.server import CarveServer, run_http_server, run_mcp_server

    # Create server with optional path (--path takes precedence over --file)
    # CarveServer resolves: file_path > carvesettings.toml > CARVE_WORKSPACE
    # CLI adds CWD as final fallback (only when invoked from command line)
    target = args.path or args.file
    perm_kwargs = {
        "read_only": args.read_only,
        "no_create": args.no_create,
        "no_delete": args.no_delete,
        "allow_custom_tools": args.allow_custom_tools,
    }
    server = CarveServer(file_path=target, **perm_kwargs)
    if server.store is None and target is None:
        server = CarveServer(file_path=Path.cwd(), **perm_kwargs)

    if args.mcp:
        # Run MCP server (stdio)
        asyncio.run(run_mcp_server(server))
        return 0
    elif args.http:
        # Run HTTP server
        run_http_server(server, host=args.host, port=args.port)
        return 0
    else:
        print("Error: Specify either --mcp or --http", file=sys.stderr)
        return 1


if __name__ == "__main__":
    sys.exit(main())
