#!/usr/bin/env python3
# src/chuk_mcp_server/cli/templates.py
"""
Scaffold project templates for ``chuk-mcp-server init``.

Pure data — no imports from the main package.
"""

from pathlib import Path


def server_py_template(project_name: str) -> str:
    """Return the content for server.py."""
    return f'''"""
{project_name} - MCP Server

A custom MCP server built with ChukMCPServer.

Features demonstrated:
- Tools: Actions Claude can perform
- Resources: Data Claude can read
- Prompts: Reusable prompt templates
- Async support: For I/O operations
- Context: Session and user tracking (optional)
- OAuth: Authentication support (optional)
"""

from chuk_mcp_server import tool, resource, prompt, run


# ============================================================================
# Tools - Actions Claude Can Perform
# ============================================================================

@tool
def hello(name: str = "World") -> str:
    """Say hello to someone."""
    return f"Hello, {{name}}!"


@tool
def add_numbers(a: int, b: int) -> int:
    """Add two numbers together."""
    return a + b


@tool
def calculate(expression: str) -> str:
    """Safely evaluate a mathematical expression."""
    try:
        # Only allow safe operations
        allowed = {{'+', '-', '*', '/', '(', ')', '.', ' '}} | set('0123456789')
        if not all(c in allowed for c in expression):
            return "Error: Invalid characters in expression"

        result = eval(expression)
        return f"{{expression}} = {{result}}"
    except Exception as e:
        return f"Error: {{str(e)}}"


# Example async tool (commented out - uncomment to use)
# @tool
# async def fetch_data(url: str) -> dict:
#     """Fetch data from a URL asynchronously."""
#     import httpx
#     async with httpx.AsyncClient() as client:
#         response = await client.get(url)
#         return {{"status": response.status_code, "data": response.json()}}


# ============================================================================
# Resources - Data Claude Can Read
# ============================================================================

@resource("config://info")
def server_info() -> dict:
    """Get server information."""
    return {{
        "name": "{project_name}",
        "version": "0.1.0",
        "description": "Custom MCP server built with ChukMCPServer"
    }}


@resource("config://capabilities")
def server_capabilities() -> dict:
    """Get server capabilities and features."""
    return {{
        "features": ["tools", "resources", "prompts"],
        "transport": "stdio/http",
        "async_support": True,
        "oauth_support": False,  # Set to True if using OAuth
    }}


# ============================================================================
# Prompts - Reusable Prompt Templates
# ============================================================================

@prompt
def code_review(code: str, language: str = "python") -> str:
    """Generate a code review prompt."""
    return f"""Please review this {{language}} code:

```{{language}}
{{code}}
```

Provide feedback on:
1. Code quality and readability
2. Potential bugs or issues
3. Best practices
4. Performance improvements
5. Security considerations
"""


@prompt
def explain_code(code: str, language: str = "python") -> str:
    """Generate a prompt to explain code."""
    return f"""Please explain what this {{language}} code does:

```{{language}}
{{code}}
```

Include:
- Overall purpose
- Step-by-step breakdown
- Key concepts used
- Potential use cases
"""


# ============================================================================
# OAuth & Context Example (commented out - uncomment to use)
# ============================================================================

# from chuk_mcp_server import requires_auth, get_user_id
#
# @tool
# @requires_auth()
# async def create_user_resource(
#     name: str,
#     _external_access_token: str | None = None
# ) -> dict:
#     """Create a user-specific resource (requires OAuth)."""
#     # Get authenticated user ID
#     from chuk_mcp_server import require_user_id
#     user_id = require_user_id()
#
#     # Use the access token to call external API
#     # headers = {{"Authorization": f"Bearer {{_external_access_token}}"}}
#
#     return {{
#         "created": name,
#         "owner": user_id,
#         "status": "success"
#     }}


if __name__ == "__main__":
    import argparse
    import sys

    # Parse command-line arguments
    parser = argparse.ArgumentParser(description="{project_name} - MCP Server")
    parser.add_argument("--stdio", action="store_true", help="Force STDIO transport mode")
    parser.add_argument("--http", action="store_true", help="Force HTTP transport mode")
    parser.add_argument("--port", type=int, default=None, help="Port for HTTP mode")
    parser.add_argument("--host", default=None, help="Host for HTTP mode")
    parser.add_argument("--debug", action="store_true", help="Enable debug logging")
    parser.add_argument(
        "--log-level",
        default="warning",
        choices=["debug", "info", "warning", "error", "critical"],
        help="Logging level (default: warning)",
    )
    parser.add_argument("--transport", choices=["stdio", "http"], help="Transport mode")

    args = parser.parse_args()

    # Determine transport mode
    if args.stdio or args.transport == "stdio":
        # Stdio mode
        run(transport="stdio", debug=args.debug, log_level=args.log_level)
    elif args.http or args.port or args.host or args.transport == "http":
        # HTTP mode
        run(
            transport="http",
            host=args.host,
            port=args.port,
            debug=args.debug,
            log_level=args.log_level,
        )
    else:
        # Default to stdio mode (best for Claude Desktop)
        run(transport="stdio", log_level=args.log_level)
'''


def pyproject_toml_template(project_name: str) -> str:
    """Return the content for pyproject.toml."""
    return f"""[project]
name = "{project_name}"
version = "0.1.0"
description = "MCP server built with ChukMCPServer"
requires-python = ">=3.11"
dependencies = [
    "chuk-mcp-server>=0.4.4",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0.0",
    "pytest-cov>=4.1.0",
    "mypy>=1.8.0",
    "ruff>=0.2.0",
]

[tool.ruff]
line-length = 120
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "W"]

[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
"""


def readme_md_template(project_name: str, project_dir: Path) -> str:
    """Return the content for README.md."""
    return f'''# {project_name}

MCP server built with [ChukMCPServer](https://github.com/chrishayuk/chuk-mcp-server).

## Transport Modes

This server supports two transport modes:

- **STDIO (default)**: For Claude Desktop and MCP clients. Communication via stdin/stdout.
- **HTTP**: For web applications, APIs, and cloud deployment. RESTful endpoints with streaming support.

## Quick Start

### Option 1: Claude Desktop (STDIO mode)

#### 1. Install dependencies
```bash
# Install globally
uv pip install --system chuk-mcp-server

# Or in a virtual environment (recommended)
uv venv
source .venv/bin/activate  # On Windows: .venv\\Scripts\\activate
uv pip install chuk-mcp-server
```

#### 2. Test the server
```bash
# Default mode is stdio - perfect for Claude Desktop
echo '{{"jsonrpc":"2.0","method":"tools/list","id":1}}' | python server.py
```

#### 3. Configure Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):

```json
{{
  "mcpServers": {{
    "{project_name}": {{
      "command": "uv",
      "args": ["--directory", "{project_dir.absolute()}", "run", "server.py"]
    }}
  }}
}}
```

Restart Claude Desktop and your server will be available!

### Option 2: Web/API (HTTP mode)

Perfect for web applications and cloud deployment.

```bash
# Start HTTP server on port 8000
python server.py --http

# Or specify custom port/host
python server.py --port 8000 --host 0.0.0.0
```

Test with curl:
```bash
curl http://localhost:8000/mcp \\
  -H "Content-Type: application/json" \\
  -d '{{"jsonrpc":"2.0","method":"tools/list","id":1}}'
```

### Option 3: Docker (Production Deployment)

Docker automatically runs the server in HTTP mode, suitable for containerized deployments.

#### Using docker-compose (easiest)
```bash
docker-compose up
```

#### Or build manually
```bash
# Build the image
docker build -t {project_name} .

# Run the container
docker run -p 8000:8000 {project_name}
```

#### Test the deployment
```bash
curl http://localhost:8000/mcp \\
  -H "Content-Type: application/json" \\
  -d '{{"jsonrpc":"2.0","method":"tools/list","id":1}}'
```

You should see:
```json
{{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {{
    "tools": [
      {{"name": "hello", "description": "Say hello to someone."}},
      {{"name": "add_numbers", "description": "Add two numbers together."}},
      {{"name": "calculate", "description": "Safely evaluate a mathematical expression."}}
    ]
  }}
}}
```

Perfect for deploying to cloud platforms like AWS, GCP, Azure, or Kubernetes!

## Available Tools

- **hello**: Say hello to someone
- **add_numbers**: Add two numbers together
- **calculate**: Safely evaluate a mathematical expression

## Available Resources

- **config://info**: Get server information
- **config://capabilities**: Get server capabilities and features

## Available Prompts

- **code_review**: Generate a code review prompt for any language
- **explain_code**: Generate a prompt to explain code

## Features

This scaffolded server demonstrates:

- **Tools**: Sync and async functions Claude can call
- **Resources**: Static and dynamic data Claude can read
- **Prompts**: Reusable prompt templates
- **Type Safety**: Automatic schema generation from type hints
- **Dual Transport**: STDIO for Claude Desktop, HTTP for web/APIs
- **OAuth** (commented): Authentication example included (uncomment to use)
- **Context** (commented): Session and user tracking example (uncomment to use)

### Adding OAuth Authentication

To add OAuth support:

1. Uncomment the OAuth example in `server.py`
2. Implement your OAuth provider (see [OAuth docs](https://github.com/chrishayuk/chuk-mcp-server/blob/main/docs/OAUTH.md))
3. Update `server_capabilities()` to set `"oauth_support": True`

### Using Context Management

To use context management (sessions, user tracking):

1. Uncomment the context example in `server.py`
2. Use `get_user_id()` to check authentication (optional)
3. Use `require_user_id()` to enforce authentication (raises error if not authenticated)
4. Use `get_session_id()` to track MCP sessions

## Development

### Run tests
```bash
uv run pytest
```

### Type checking
```bash
uv run mypy server.py
```

### Linting
```bash
uv run ruff check .
```

## Command-Line Options

The server automatically detects the best transport mode, but you can override:

```bash
# Force STDIO mode (default)
python server.py --stdio
python server.py --transport=stdio

# Force HTTP mode
python server.py --http
python server.py --port 8000
python server.py --host 0.0.0.0
python server.py --transport=http
```

## Customization

Edit `server.py` to add your own tools, resources, and prompts:

```python
from chuk_mcp_server import tool, resource, prompt, run

# Add your custom tool
@tool
def my_custom_tool(param: str) -> str:
    """Your custom tool description."""
    return f"Result: {{param}}"

# Add your custom resource
@resource("custom://data")
def my_resource() -> dict:
    """Your custom resource."""
    return {{"data": "value"}}

# Add your custom prompt
@prompt
def my_prompt_template(topic: str) -> str:
    """Custom prompt template."""
    return f"Please write about: {{topic}}"

# Add async tools for I/O operations
@tool
async def fetch_api(url: str) -> dict:
    """Fetch data from API asynchronously."""
    import httpx
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        return response.json()

if __name__ == "__main__":
    run(transport="stdio")  # or just run() for auto-detection
```

### Advanced Features

For OAuth authentication, context management, and more advanced features, see:

- [ChukMCPServer Documentation](https://github.com/chrishayuk/chuk-mcp-server)
- [OAuth Guide](https://github.com/chrishayuk/chuk-mcp-server/blob/main/docs/OAUTH.md)
- [Context Architecture](https://github.com/chrishayuk/chuk-mcp-server/blob/main/docs/CONTEXT_ARCHITECTURE.md)
- [Example: LinkedIn OAuth Integration](https://github.com/chrishayuk/chuk-mcp-linkedin)
'''


def gitignore_template() -> str:
    """Return the content for .gitignore."""
    return """# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Virtual environments
venv/
env/
ENV/

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~

# Testing
.pytest_cache/
.coverage
htmlcov/

# Type checking
.mypy_cache/
.dmypy.json
dmypy.json

# Ruff
.ruff_cache/

# OS
.DS_Store
Thumbs.db
"""


def dockerfile_template() -> str:
    """Return the content for Dockerfile."""
    return """FROM python:3.11-slim

WORKDIR /app

# Install uv
RUN pip install uv

# Copy project files
COPY pyproject.toml ./
COPY server.py ./

# Install dependencies using uv
RUN uv pip install --system --no-cache chuk-mcp-server>=0.4.4

# Expose HTTP port
EXPOSE 8000

# Run server in HTTP mode for web/API access
CMD ["python", "server.py", "--port", "8000", "--host", "0.0.0.0"]
"""


def docker_compose_template(project_name: str) -> str:
    """Return the content for docker-compose.yml."""
    return f"""version: '3.8'

services:
  {project_name}:
    build: .
    ports:
      - "8000:8000"
    environment:
      - MCP_TRANSPORT=http
    restart: unless-stopped
"""
