"""api.v1.jobs — Async job management endpoints."""
from __future__ import annotations
import json
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from typing import Any, Dict, Optional
from agentpaas.api.deps import get_tenant, get_database
from agentpaas.api.middleware.auth import TenantContext
from agentpaas.db.models import Database
from agentpaas.engine.queue import Job
from agentpaas.engine import dispatch_async, get_queue

router = APIRouter(prefix="/jobs", tags=["jobs"])

def _ensure_job_owned(job, tenant: TenantContext):
    """audit/AUDIT_2026-06-05.md #28 — both `get_job` and `cancel_job`
    used to look up by job_id alone with no tenant scope. A holder of any
    valid API key could read or cancel any other tenant's job by guessing
    a `job_8e5f2a` UUID. 404 (not 403) avoids an id oracle: same response
    for "job does not exist" vs "exists but belongs to another tenant"."""
    if not job:
        raise HTTPException(404, {"error": {"code": "JOB_NOT_FOUND"}})
    if getattr(job, "tenant_id", "") != tenant.tenant_id:
        raise HTTPException(404, {"error": {"code": "JOB_NOT_FOUND"}})


@router.get("/{job_id}")
async def get_job(job_id: str, tenant: TenantContext = Depends(get_tenant)):
    queue = get_queue()
    job = queue.get_job(job_id)
    _ensure_job_owned(job, tenant)
    return {"job_id": job.id, "status": job.status, "result": job.result if job.status == "completed" else None,
            "error": job.error if job.status == "failed" else None, "created_at": job.created_at}

@router.post("/{job_id}/cancel")
async def cancel_job(job_id: str, tenant: TenantContext = Depends(get_tenant)):
    queue = get_queue()
    job = queue.get_job(job_id)
    _ensure_job_owned(job, tenant)
    queue.update_job(job_id, status="cancelled")
    return {"message": "Job cancelled", "job_id": job_id}
