from __future__ import annotations

from fastapi import HTTPException


def truncate_preflight_error(exc: Exception, limit: int = 300) -> str:
    text = str(exc).strip() or exc.__class__.__name__
    if len(text) <= limit:
        return text
    return text[:limit].rstrip() + "..."


async def preflight_soql_query(
    gateway,
    soql: str,
    *,
    user: str = "soql-preflight",
    ip: str = "0.0.0.0",
    allow_no_limit: bool = True,
) -> None:
    """Validate SOQL against security policy + Salesforce execution.

    This helper intentionally runs a lightweight execution probe (first page only)
    so malformed or org-invalid queries are rejected before persistence.
    """
    from .salesforce_gateway import SecurityViolation

    query = str(soql or "").strip()
    if not query:
        raise HTTPException(400, "SOQL query is required")

    ctx = {
        "admin_override": False,
        "user": user,
        "ip": ip,
        "user_is_admin": False,
        "plan_allowlist": {},
        "allow_no_limit": allow_no_limit,
    }

    try:
        touchpoints = await gateway._security_check(query, ctx)
        invalid_fields = await gateway._find_inaccessible_fields(touchpoints)
        if invalid_fields:
            detail = ", ".join(sorted(invalid_fields))
            raise HTTPException(400, f"SOQL references inaccessible fields: {detail}")

        async for _ in gateway.paginate_soql(
            query,
            user=user,
            ip=ip,
            allow_no_limit=allow_no_limit,
        ):
            break
    except HTTPException:
        raise
    except SecurityViolation as exc:
        raise HTTPException(400, f"SOQL blocked by security policy: {exc}") from exc
    except Exception as exc:  # noqa: BLE001 - map backend/SF errors to clear 400
        raise HTTPException(
            400, f"SOQL preflight failed: {truncate_preflight_error(exc)}"
        ) from exc
