"""
Docker and container helper functions for Dazzle CLI.

Contains utilities for Docker container management and
production artifact generation (Dockerfile, docker-compose, etc.).
"""

from __future__ import annotations

from pathlib import Path


def get_container_name(project_root: Path, project_name: str | None = None) -> str:
    """Get the Docker container name for a project.

    Uses project_name from manifest if provided, otherwise falls back to directory name.
    """
    base_name = project_name or project_root.resolve().name
    return f"dazzle-{base_name}"


def is_container_running(container_name: str) -> bool:
    """Check if a Docker container is running."""
    import subprocess

    try:
        result = subprocess.run(
            ["docker", "ps", "-q", "-f", f"name={container_name}"],
            capture_output=True,
            text=True,
            timeout=5,
        )
        return bool(result.stdout.strip())
    except (subprocess.SubprocessError, FileNotFoundError):
        return False


def generate_production_main(app_name: str, include_frontend: bool) -> str:
    """Generate production-ready main.py entry point."""
    return f'''"""
Production entry point for {app_name}.

Auto-generated by Dazzle Dazzle build.

Usage:
    python main.py                    # Run with defaults
    python main.py --port 8080        # Custom port
    python main.py --host 0.0.0.0     # Bind to all interfaces

Environment variables:
    PORT          - Server port (default: 8000)
    HOST          - Server host (default: 0.0.0.0)
    DATABASE_URL  - SQLite database path (default: ./data/app.db)
    LOG_LEVEL     - Logging level (default: INFO)
"""

import argparse
import logging
import os
from pathlib import Path

# Configure logging
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
logging.basicConfig(
    level=getattr(logging, log_level, logging.INFO),
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)


def main():
    parser = argparse.ArgumentParser(description="{app_name} - Dazzle Production Server")
    parser.add_argument("--port", type=int, default=int(os.getenv("PORT", "8000")))
    parser.add_argument("--host", type=str, default=os.getenv("HOST", "0.0.0.0"))
    parser.add_argument("--reload", action="store_true", help="Enable auto-reload (dev only)")
    args = parser.parse_args()

    # Database setup
    db_path = os.getenv("DATABASE_URL", "./data/app.db")
    Path(db_path).parent.mkdir(parents=True, exist_ok=True)

    logger.info(f"Starting {app_name}")
    logger.info(f"  Host: {{args.host}}:{{args.port}}")
    logger.info(f"  Database: {{db_path}}")

    try:
        import uvicorn
        from dazzle_back.runtime import create_app_from_json

        spec_path = Path(__file__).parent / "backend" / "backend-spec.json"
        if not spec_path.exists():
            logger.error(f"Backend spec not found: {{spec_path}}")
            return 1

        app = create_app_from_json(str(spec_path), db_path=db_path)

        uvicorn.run(
            app,
            host=args.host,
            port=args.port,
            reload=args.reload,
            log_level=log_level.lower(),
        )

    except ImportError as e:
        logger.error(f"Missing dependencies: {{e}}")
        logger.error("Install with: pip install -r requirements.txt")
        return 1
    except Exception as e:
        logger.error(f"Failed to start: {{e}}")
        return 1

    return 0


if __name__ == "__main__":
    exit(main())
'''


def generate_requirements() -> str:
    """Generate requirements.txt for production."""
    return """# Runtime Production Dependencies
# Generated by: dazzle build

# Core runtime
dazzle-app-back>=0.4.0
fastapi>=0.100.0
uvicorn[standard]>=0.22.0
pydantic>=2.0.0

# Database
aiosqlite>=0.19.0
asyncpg>=0.29.0

# Optional: Redis (for Celery workers / caching)
# redis>=5.0.0

# Optional: Production server
gunicorn>=21.0.0

# Optional: Monitoring
prometheus-fastapi-instrumentator>=6.0.0
"""


def generate_dockerfile(app_name: str, include_frontend: bool) -> str:
    """Generate multi-stage Dockerfile."""
    frontend_stage = ""
    copy_frontend = ""
    if include_frontend:
        frontend_stage = """
# Frontend build stage
FROM node:20-alpine AS frontend-builder
WORKDIR /app/frontend
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ ./
RUN npm run build
"""
        copy_frontend = """
# Copy frontend build
COPY --from=frontend-builder /app/frontend/dist /app/static
ENV STATIC_FILES_DIR=/app/static
"""

    return f"""# Dockerfile for {app_name}
# Generated by: dazzle build
{frontend_stage}
# Backend build stage
FROM python:3.11-slim AS backend

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
{copy_frontend}
# Copy backend
COPY backend/ ./backend/
COPY main.py .

# Create data directory
RUN mkdir -p /app/data

# Environment
ENV PORT=8000
ENV HOST=0.0.0.0
ENV DATABASE_URL=/app/data/app.db
ENV LOG_LEVEL=INFO

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
    CMD curl -f http://localhost:${{PORT}}/health || exit 1

EXPOSE ${{PORT}}

CMD ["python", "main.py"]
"""


def generate_docker_compose(app_name: str) -> str:
    """Generate docker-compose.yml for local deployment."""
    return f"""# Docker Compose for {app_name}
# Generated by: dazzle build

version: "3.8"

services:
  app:
    build: .
    ports:
      - "${{PORT:-8000}}:8000"
    environment:
      - PORT=8000
      - HOST=0.0.0.0
      - DATABASE_URL=/app/data/app.db
      - LOG_LEVEL=${{LOG_LEVEL:-INFO}}
    volumes:
      - app-data:/app/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 10s

volumes:
  app-data:
    driver: local
"""


def generate_local_compose(app_name: str) -> str:
    """Generate docker-compose.local.yml with Postgres + Redis backing services."""
    return f"""# Local backing services for {app_name}
# Generated by: dazzle build
#
# Start with: docker compose -f docker-compose.local.yml up -d
# Stop with:  docker compose -f docker-compose.local.yml down
# Reset data: docker compose -f docker-compose.local.yml down -v

services:
  postgres:
    image: postgres:16-alpine
    ports:
      - "${{PGPORT:-5433}}:5432"
    environment:
      POSTGRES_DB: {app_name}
      POSTGRES_USER: {app_name}
      POSTGRES_PASSWORD: localdev
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U {app_name}"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "${{REDIS_PORT:-6380}}:6379"
    volumes:
      - redisdata:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

volumes:
  pgdata:
    driver: local
  redisdata:
    driver: local
"""


def generate_local_run_script(app_name: str) -> str:
    """Generate scripts/run_local.sh for full-framework local development."""
    return f"""#!/usr/bin/env bash
# Local development runner for {app_name}
# Generated by: dazzle build
#
# Prerequisites:
#   docker compose -f docker-compose.local.yml up -d
#   pip install -e .   # or: pip install dazzle
#
# Usage:
#   ./scripts/run_local.sh              # Start dev server
#   ./scripts/run_local.sh --reload     # With hot-reload

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${{BASH_SOURCE[0]}}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"

# Load .env if present
if [ -f "$PROJECT_ROOT/.env" ]; then
    set -a
    source "$PROJECT_ROOT/.env"
    set +a
fi

# Database (Postgres via docker-compose.local.yml)
export DATABASE_URL="${{DATABASE_URL:-postgresql://{app_name}:{app_name}@localhost:${{PGPORT:-5433}}/{app_name}}}"

# Redis (via docker-compose.local.yml)
export REDIS_URL="${{REDIS_URL:-redis://localhost:${{REDIS_PORT:-6380}}/0}}"

# Server settings
export PORT="${{PORT:-8000}}"
export HOST="${{HOST:-0.0.0.0}}"
export LOG_LEVEL="${{LOG_LEVEL:-INFO}}"

# Dazzle project root (for create_app_factory)
export DAZZLE_PROJECT_ROOT="${{DAZZLE_PROJECT_ROOT:-$PROJECT_ROOT}}"

echo "Starting {app_name} (local dev)"
echo "  Database: $DATABASE_URL"
echo "  Redis:    $REDIS_URL"
echo "  Server:   http://$HOST:$PORT"
echo ""

exec uvicorn \\
    "dazzle_back.runtime.server:create_app_factory" \\
    --factory \\
    --host "$HOST" \\
    --port "$PORT" \\
    --log-level "${{LOG_LEVEL,,}}" \\
    "$@"
"""


def generate_env_template(app_name: str) -> str:
    """Generate environment template."""
    return f"""# Environment configuration for {app_name}
# Generated by: dazzle build
#
# Copy this file to .env and customize:
#   cp .env.example .env

# Server configuration
PORT=8000
HOST=0.0.0.0

# Database (Postgres via docker-compose.local.yml)
# DATABASE_URL=postgresql://{app_name}:{app_name}@localhost:5433/{app_name}
# Fallback: SQLite (no docker required)
DATABASE_URL=./data/app.db

# Redis (via docker-compose.local.yml)
# REDIS_URL=redis://localhost:6380/0

# Logging
LOG_LEVEL=INFO

# Security (generate your own secret key!)
# SECRET_KEY=your-secret-key-here

# CORS (comma-separated origins)
# CORS_ORIGINS=http://localhost:3000,https://myapp.com

# Optional: Auth settings
# AUTH_ENABLED=true
# JWT_SECRET=your-jwt-secret

# Optional: File uploads
# FILES_ENABLED=true
# FILES_PATH=./uploads
# MAX_FILE_SIZE=10485760

# Optional: Celery workers (requires Redis)
# USE_CELERY_PROCESSES=true

# Production settings
# WORKERS=4
# TIMEOUT=30
"""
