"""Abstract base class for form adapters."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Any


class FormAdapter(ABC):
    """Adapter for fetching and saving Form.io component trees.

    Implementations handle the specifics of where forms live in the BPA API
    (roles, services, print documents, etc.) and how to round-trip them.
    """

    @abstractmethod
    async def fetch(self, target_id: str) -> list[dict[str, Any]]:
        """Fetch the component tree for the given target.

        Args:
            target_id: Identifier of the resource owning the form.

        Returns:
            List of top-level Form.io components.
        """
        ...

    @abstractmethod
    async def save(self, components: list[dict[str, Any]]) -> None:
        """Save a modified component tree back to the BPA API.

        Must be called after fetch() so the adapter has the envelope
        (surrounding metadata) needed for a round-trip PUT.

        Args:
            components: The modified Form.io component list.

        Raises:
            RuntimeError: If fetch() was not called first.
        """
        ...

    @property
    @abstractmethod
    def label(self) -> str:
        """Human-readable description of this adapter's target.

        Used in diff reports, error messages, and audit logs.
        """
        ...
