# 🚀 Modal Deployment Script ({{ deployment_mode|title }} Configuration)
# Generated by modal-for-noobs - https://github.com/arthrod/modal-for-noobs
# Deployment Mode: {{ deployment_mode }}
# Description: {{ description }}
# Timeout: {{ timeout_seconds }}s | Scale: {{ min_containers }}-{{ max_containers }} containers

import modal
import sys
import os
from pathlib import Path
from datetime import datetime
{% if provision_logging %}
from loguru import logger
{% endif %}
{% if enable_dashboard or deployment_mode in ['marimo', 'gradio-jupyter'] %}
import asyncio
import subprocess
{% endif %}
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
import gradio as gr
from gradio.routes import mount_gradio_app

# Configuration constants
APP_NAME = "{{ app_name }}"
APP_TITLE = "{{ app_name }} - Modal Deployment"
APP_DESCRIPTION = "{{ description }}"
DEPLOYMENT_MODE = "{{ deployment_mode }}"
TIMEOUT_SECONDS = {{ timeout_seconds }}
MAX_CONTAINERS = {{ max_containers }}
MIN_CONTAINERS = {{ min_containers }}

{% if provision_logging %}
# Configure logging
logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
{% endif %}

# Create Modal App
app = modal.App(APP_NAME)

{% if provision_nfs %}
# Persistent storage configuration
MOUNT_PATH = "/workspace"
volume = modal.Volume.persisted(f"{APP_NAME}-volume")
{% endif %}

{% if has_secrets %}
# Secrets configuration
secrets = [
    {% for secret in secrets %}
    modal.Secret.from_name("{{ secret }}"),
    {% endfor %}
]
{% endif %}

# Container Image Configuration
{{ image_config }}

{% if has_env_vars %}
# Environment variables
env_vars = {
    {% for key, value in environment_variables.items() %}
    "{{ key }}": "{{ value }}",
    {% endfor %}
}
{% else %}
env_vars = {}
{% endif %}

# Original Application Code
{{ original_code }}

{% if has_remote_functions %}
# Remote Functions
{% for func in remote_functions %}
@app.function(
    image=image,
    {% if func.gpu %}
    gpu={{ func.gpu | format_gpu }},
    {% endif %}
    {% if func.num_gpus %}
    gpu_count={{ func.num_gpus }},
    {% endif %}
    {% if func.keep_warm %}
    keep_warm={{ func.keep_warm }},
    {% endif %}
    timeout={{ func.timeout }},
    memory={{ func.memory }},
    cpu={{ func.cpu }},
    {% if func.secret %}
    secrets=[modal.Secret.from_name("{{ func.secret }}")],
    {% endif %}
    {% if func.volume and provision_nfs %}
    volumes={MOUNT_PATH: volume},
    {% endif %}
    {% if func.schedule %}
    schedule=modal.Cron("{{ func.schedule }}"),
    {% endif %}
)
def {{ func.name }}():
    """Remote function: {{ func.name }}"""
    {% if provision_logging %}
    logger.info("Executing remote function: {{ func.name }}")
    {% endif %}
    pass

{% endfor %}
{% endif %}

# Main deployment function
@app.function(
    image=image,
    {% if has_gpu %}
    gpu="{{ gpu_type }}",
    {% if num_gpus > 0 %}
    gpu_count={{ num_gpus }},
    {% endif %}
    {% endif %}
    min_containers={{ min_containers }},
    max_containers={{ max_containers }},
    timeout={{ timeout_seconds }},
    memory={{ memory_mb }},
    cpu={{ cpu }},
    {% if has_secrets %}
    secrets=secrets,
    {% endif %}
    {% if provision_nfs %}
    volumes={MOUNT_PATH: volume},
    {% endif %}
    env=env_vars,
)
@modal.concurrent(max_inputs={{ concurrent_inputs }})
@modal.asgi_app()
def deploy_gradio():
    """Deploy Gradio app with Modal infrastructure."""
    
    {% if provision_logging %}
    logger.info(f"Starting Modal deployment in {DEPLOYMENT_MODE} mode")
    {% endif %}
    
    {% if has_gpu %}
    # Check GPU availability
    try:
        import torch
        gpu_available = torch.cuda.is_available()
        gpu_name = torch.cuda.get_device_name(0) if gpu_available else "None"
        {% if provision_logging %}
        logger.info(f"GPU Status - Available: {gpu_available}, Device: {gpu_name}")
        {% endif %}
    except ImportError:
        gpu_available = False
        gpu_name = "None"
        {% if provision_logging %}
        logger.warning("PyTorch not available, GPU detection skipped")
        {% endif %}
    {% endif %}
    
    # Detect Gradio Interface
    demo = None
    interface_names = ['demo', 'app', 'interface', 'iface']
    
    for name in interface_names:
        if name in globals() and hasattr(globals()[name], 'launch'):
            demo = globals()[name]
            {% if provision_logging %}
            logger.info(f"Found Gradio interface: {name}")
            {% endif %}
            break
    
    if demo is None:
        for var_name, var_value in globals().items():
            if hasattr(var_value, 'queue') and hasattr(var_value, 'launch'):
                demo = var_value
                {% if provision_logging %}
                logger.info(f"Found Gradio interface through scanning: {var_name}")
                {% endif %}
                break
    
    if demo is None:
        {% if provision_logging %}
        logger.error("No Gradio interface found")
        {% endif %}
        raise ValueError("Could not find Gradio interface")
    
    # Configure demo queue
    demo.queue(max_size=20)
    
    # FastAPI Setup
    fastapi_app = FastAPI(
        title=APP_TITLE,
        description=APP_DESCRIPTION,
        version="1.0.0",
        docs_url="/docs",
        redoc_url="/redoc"
    )
    
    {% if enable_monitoring %}
    # Add monitoring endpoints
    @fastapi_app.get("/health")
    async def health_check():
        return {
            "status": "healthy",
            "app_name": APP_NAME,
            "deployment_mode": DEPLOYMENT_MODE,
            "timestamp": datetime.now().isoformat(),
            {% if has_gpu %}
            "gpu_available": gpu_available,
            "gpu_name": gpu_name,
            {% endif %}
        }
    
    @fastapi_app.get("/info")
    async def deployment_info():
        return {
            "app_name": APP_NAME,
            "deployment_mode": DEPLOYMENT_MODE,
            "modal_version": modal.__version__,
            "python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
            "timeout_seconds": TIMEOUT_SECONDS,
            "max_containers": MAX_CONTAINERS,
            "min_containers": MIN_CONTAINERS,
            {% if has_gpu %}
            "gpu_enabled": True,
            "gpu_type": "{{ gpu_type }}",
            {% if num_gpus > 0 %}
            "gpu_count": {{ num_gpus }},
            {% endif %}
            {% endif %}
        }
    {% endif %}
    
    {% if provision_logging %}
    logger.info("Mounting Gradio app to FastAPI")
    {% endif %}
    
    # Mount Gradio app
    return mount_gradio_app(fastapi_app, demo, path="/")

# Run the app
if __name__ == "__main__":
    app.run()