"""Binding result model for resolved resource slot bindings.

When a tool is activated within a plan context, each of its
:class:`~cleveragents.domain.models.core.tool.ResourceSlot` declarations
must be resolved to a concrete resource.  The resolution produces a
:class:`BindingResult` for every slot, capturing the outcome (or
deferral) of the resolution process.

Three binding modes are supported:

| Mode          | Determination                                |
|---------------|----------------------------------------------|
| ``contextual``| Resolved from the plan's project at runtime  |
| ``static``    | Hardcoded at registration via ``static_resource`` |
| ``parameter`` | Passed as a tool argument at invocation time |

See Also:
    - :class:`~cleveragents.domain.models.core.tool.ResourceSlot`
    - :mod:`~cleveragents.application.services.binding_resolution_service`
"""

from __future__ import annotations

from pydantic import BaseModel, ConfigDict, Field


class BindingResult(BaseModel):
    """Outcome of resolving a single resource slot.

    Produced by
    :meth:`~cleveragents.application.services.binding_resolution_service.BindingResolutionService.resolve`
    for each :class:`~cleveragents.domain.models.core.tool.ResourceSlot`
    on a tool.

    When ``deferred`` is ``True`` the slot uses *parameter* binding and
    will only be fully resolved at invocation time.
    """

    slot_name: str = Field(
        ...,
        min_length=1,
        description="Name of the resource slot being resolved",
    )
    resource_id: str | None = Field(
        default=None,
        description=(
            "ULID of the resolved resource (None for deferred parameter bindings)"
        ),
    )
    resource_name: str | None = Field(
        default=None,
        description="Namespaced name of the resolved resource",
    )
    binding_mode: str = Field(
        ...,
        description=(
            "How the binding was resolved: 'contextual', 'static', or 'parameter'"
        ),
    )
    deferred: bool = Field(
        default=False,
        description=(
            "True when the binding is deferred to invocation time (parameter binding)"
        ),
    )

    model_config = ConfigDict(
        frozen=True,
        str_strip_whitespace=True,
    )
