"""Cockpit Backend - entrypoint.

Corrigida a quebra de sintaxe que existia (faltava async def health) e
restaurados routers ausentes (routes_state, routes_feed, ws).
"""
from contextlib import asynccontextmanager
import asyncio
import os
from pathlib import Path
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse

from config.settings import settings
from core import db
from core.car import claim_instance, get_car, release_instance
from core.executor import recover_interrupted_runs
from core.orchestrator import recover_interrupted_requests
from core.state import state
from core.adapters import get_adapter
from api import routes_auth, routes_jobs, routes_state, routes_feed, routes_chat, routes_terminal, routes_ecosystem, routes_knowledge, routes_runtime, ws
from security.web import SecurityMiddleware

@asynccontextmanager
async def lifespan(app: FastAPI):
    settings.validate_runtime_security()
    # Cockpit Adaptive Runtime: registra a instancia e detecta servidor
    # duplicado antes de qualquer trabalho. Nenhum processo e encerrado.
    try:
        car = get_car()
        car.register_owned_pid(os.getpid(), "cockpit-api")
        claim = claim_instance(host=settings.cockpit_host, port=settings.cockpit_port)
        app.state.car_instance = claim
        if claim.get("acquired") is False:
            other = claim.get("duplicate_of") or {}
            print(
                "[car] possivel servidor duplicado: instancia anterior pid="
                + str(other.get("pid"))
                + " continua ativa. Nenhum processo foi encerrado."
            )
        car.snapshot()
    except Exception as exc:
        print("[car] inicializacao adiada: " + type(exc).__name__)
    db.migrate()
    # Retoma apenas Runs locais com plano versionado e ferramentas idempotentes allowlisted.
    # Nenhum conector de provedor ou handoff e despachado no startup.
    try:
        app.state.executor_recovery = await recover_interrupted_runs(db.connection())
    except Exception as exc:
        app.state.executor_recovery = []
        print("[executor-recovery] local recovery deferred: " + type(exc).__name__)
    # Solicitacoes presas em 'processing' (crash no meio do planejamento) sao
    # marcadas como falha real; nada e replanejado e nenhum job e duplicado.
    try:
        app.state.orchestration_recovery = recover_interrupted_requests(db.connection())
    except Exception as exc:
        app.state.orchestration_recovery = []
        print("[orchestration-recovery] reconciliation deferred: " + type(exc).__name__)
    db.seed_if_empty()
    state.load_from_db()
    app.state.adapter = get_adapter(settings.cockpit_adapter)
    app.state.adapter_task = asyncio.create_task(_run_adapter_stream(app))
    try:
        yield
    finally:
        if app.state.adapter_task:
            app.state.adapter_task.cancel()
        try:
            release_instance()
        except Exception:
            pass
        await db.close()

async def _run_adapter_stream(app: FastAPI):
    adapter = app.state.adapter
    try:
        async for message in adapter.stream():
            await ws.broadcast(message)
    except asyncio.CancelledError:
        pass
    except Exception as e:
        print("[adapter-stream] error: " + str(e))

app = FastAPI(title="Cockpit Backend", version="0.1.0", lifespan=lifespan)
app.state.cockpit_settings = settings

app.add_middleware(SecurityMiddleware)
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.allowed_origins_list,
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
    allow_headers=["Content-Type", "X-CSRF-Token"],
)

app.include_router(routes_auth.router)
app.include_router(routes_state.router)
app.include_router(routes_feed.router)
app.include_router(routes_chat.router)
app.include_router(routes_terminal.router)
app.include_router(routes_jobs.router)
app.include_router(routes_jobs.pages)
app.include_router(routes_ecosystem.router)
app.include_router(routes_knowledge.knowledge_router)
app.include_router(routes_knowledge.review_router)
app.include_router(routes_knowledge.research_router)
app.include_router(routes_knowledge.agents_router)
app.include_router(routes_runtime.runtime_router)
app.include_router(ws.router)

@app.get("/api/health")
async def health():
    return {"data": {"status": "ok", "version": app.version}, "error": None}

_frontend = Path(__file__).parent / "frontend"

@app.get("/", include_in_schema=False)
async def frontend_index():
    return FileResponse(_frontend / "index.html")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("main:app", host=settings.cockpit_host, port=settings.cockpit_port, reload=True)
