# Extension contracts for reusable site components with shared planning and validation.
from dataclasses import dataclass
from typing import Callable


@dataclass(frozen=True)
class SiteComponent:
    """Register a reusable geometry algorithm, not a complete building preset.

    Args:
        name: Unique capability identifier used by Feature.
        realize: Callable receiving Compiler context and the resolved feature dictionary.
            It must set feature['target'] to an accessible feet position, append a
            metadata feature with owner/kind/target, and record supports/reservations.
        scale: Inclusive minimum and maximum plot width/depth.
        rule: Optional validator receiving Grid, metadata and Report.
        version: Explicit implementation version retained in the resolved plan.
    """
    name: str
    realize: Callable
    scale: tuple[int, int] = (5, 11)
    rule: Callable | None = None
    version: str = '1'


SITE_COMPONENTS = {}
BUILTIN_FEATURES = ('pool', 'field', 'well', 'windmill', 'landing', 'garden')


def register_site_component(component: SiteComponent):
    """Integrate a component with plot allocation, route planning and validation."""
    if component.name in SITE_COMPONENTS or component.name in BUILTIN_FEATURES:
        raise ValueError(f'component name already registered: {component.name}')
    if not 3 <= component.scale[0] <= component.scale[1] <= 15:
        raise ValueError('component plot scale must lie in 3..15')
    SITE_COMPONENTS[component.name] = component
    return component
