"""
Z-Arch Extension Base Contract
-----------------------------------------------
Defines the authoritative interface implemented by Z-Arch extensions.

`ZArchExtension` establishes:
  - a required `claim(...)` selector for matching extension blocks in `zarch.yaml`
  - optional lifecycle hook methods for project bootstrap and deploy phases
  - a canonical lifecycle hook name set consumed by core dispatch logic

Execution locality (local vs remote) is enforced by Z-Arch core policy and is
not configurable by extensions. Extension implementations should be deterministic
and side-effect aware for repeated lifecycle dispatches.

Copyright © 2026 RAM Cloud Code LLC
Licensed under the Apache License, Version 2.0.
"""

# zarch/extensions/base.py
from __future__ import annotations
from typing import Any, Dict
from zarch.extensions.context import ZArchContext

LIFECYCLE_HOOK_NAMES: tuple[str, ...] = (
    "pre_project_bootstrap",
    "post_project_bootstrap",
    "pre_service_deploy",
    "post_service_deploy",
    "pre_gateway_deploy",
    "post_gateway_deploy",
    "pre_job_deploy",
    "post_job_deploy",
    "pre_scheduler_deploy",
    "post_scheduler_deploy",
    "pre_topic_deploy",
    "post_topic_deploy",
)


class ZArchExtension:
    """
    Base class for all Z Arch extension modules.

    Extensions may implement any subset of the lifecycle callbacks.
    Z Arch will automatically skip callbacks that are not overridden.

    Each extension claims specific extension blocks by inspecting the
    extension name and the extension configuration block from zarch.yaml.
    """

    def claim(self, extension_name: str, extension_block: Dict[str, Any]) -> bool:
        """
        Return True if this extension should handle the extension block.

        Parameters:
            extension_name: The key of the extension block inside zarch.yaml.
            extension_block: The configuration dictionary for that block.

        This method determines whether Z Arch dispatches lifecycle events
        to this extension instance.
        """
        raise NotImplementedError("Extension must implement the claim method.")

    @classmethod
    def lifecycle_hooks(cls) -> tuple[str, ...]:
        """Return the lifecycle hook names supported by Z-Arch core."""
        return LIFECYCLE_HOOK_NAMES


    # Lifecycle hooks
    # ------------------------------------------------------------

    def pre_project_bootstrap(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def post_project_bootstrap(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def pre_service_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def post_service_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def pre_gateway_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def post_gateway_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def pre_job_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def post_job_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def pre_scheduler_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def post_scheduler_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def pre_topic_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass


    def post_topic_deploy(
        self,
        project_context: "ZArchContext",
        extension_configuration: Dict[str, Any]
    ) -> None:
        pass
