# DOCS_REF:
# - docs/user/07-stateless-op-scopes.md
# - docs/user/reference/api-surface.md
# DOCS_SYNC:
# - If stateless_op registration inputs/defaults change, update stateless docs
#   and examples/docs/stateless_op_scopes_example.py.

from __future__ import annotations

import uuid
from typing import Any, Callable

from flownet.core.stateless import StatelessOpConfig, StatelessOpRef, StatelessScope
from flownet.runtime import stateless_ops


def stateless_op(
    fn: Callable[..., Any],
    *,
    scope: StatelessScope = "serialized",
    name: str | None = None,
    deterministic: bool | None = None,
    side_effects: bool | None = None,
    cost_hint: str | None = None,
    batchable: bool | None = None,
    timeout_ms: int | None = None,
    metadata: dict[str, Any] | None = None,
) -> StatelessOpRef:
    config = StatelessOpConfig(
        scope=scope,
        deterministic=deterministic,
        side_effects=side_effects,
        cost_hint=cost_hint,
        batchable=batchable,
        timeout_ms=timeout_ms,
        metadata=metadata or {},
    )
    op_id = uuid.uuid4().hex
    op_ref = stateless_ops.register_stateless_op(
        fn,
        op_id=op_id,
        config=config,
        name=name,
    )
    return op_ref


def stateless(
    *,
    scope: StatelessScope = "serialized",
    name: str | None = None,
    deterministic: bool | None = None,
    side_effects: bool | None = None,
    cost_hint: str | None = None,
    batchable: bool | None = None,
    timeout_ms: int | None = None,
    metadata: dict[str, Any] | None = None,
):
    def decorator(fn: Callable[..., Any]) -> StatelessOpRef:
        return stateless_op(
            fn,
            scope=scope,
            name=name or getattr(fn, "__name__", None),
            deterministic=deterministic,
            side_effects=side_effects,
            cost_hint=cost_hint,
            batchable=batchable,
            timeout_ms=timeout_ms,
            metadata=metadata,
        )

    return decorator


__all__ = ["StatelessOpConfig", "StatelessOpRef", "StatelessScope", "stateless", "stateless_op"]
