"""Bundled SDK clients with one shared context."""

from __future__ import annotations

from pathlib import Path
from typing import Callable

from ..git import GitClient
from .branches import BranchClient
from .context import _Context
from .repository import RepositoryClient
from .workflows import WorkflowClient
from .workspace import LocalState, TrackedConfig


class Clients:
    """Bundle of use-case-specific clients over one shared context."""

    def __init__(
        self,
        git_client: GitClient | None = None,
        tracked_config: TrackedConfig | None = None,
        local_state: LocalState | None = None,
        reconciliation_editor: Callable[[str, Path], str] | None = None,
    ) -> None:
        context = _Context(
            git_client=git_client,
            tracked_config=tracked_config,
            local_state=local_state,
            reconciliation_editor=reconciliation_editor,
        )
        object.__setattr__(self, "_context", context)
        object.__setattr__(self, "repository", RepositoryClient(context))
        object.__setattr__(self, "branches", BranchClient(context))
        object.__setattr__(self, "workflows", WorkflowClient(context))

    @property
    def git_client(self) -> GitClient:
        """Expose the shared Git client."""
        return self._context.git_client

    @property
    def tracked_config(self) -> TrackedConfig:
        """Expose the tracked config helper."""
        return self._context.tracked_config

    @property
    def local_state(self) -> LocalState:
        """Expose the local-state helper."""
        return self._context.local_state

    @property
    def reconciliation_editor(self):
        """Expose the reconciliation editor callback."""
        return self._context.reconciliation_editor

    def __getattr__(self, name: str):
        for client in (self.repository, self.branches, self.workflows):
            if hasattr(client, name):
                return getattr(client, name)
        if hasattr(self._context, name):
            return getattr(self._context, name)
        raise AttributeError(name)

    def __setattr__(self, name: str, value: object) -> None:
        if name in {
            "_context",
            "repository",
            "branches",
            "workflows",
        }:
            object.__setattr__(self, name, value)
            return
        for client in (self.repository, self.branches, self.workflows):
            if hasattr(client, name):
                setattr(client, name, value)
                return
        if hasattr(self._context, name):
            setattr(self._context, name, value)
            return
        object.__setattr__(self, name, value)


def build_clients(
    git_client: GitClient | None = None,
    tracked_config: TrackedConfig | None = None,
    local_state: LocalState | None = None,
    reconciliation_editor: Callable[[str, Path], str] | None = None,
) -> Clients:
    """Build the split client set around one shared context."""
    return Clients(
        git_client=git_client,
        tracked_config=tracked_config,
        local_state=local_state,
        reconciliation_editor=reconciliation_editor,
    )
