"""Contained-branch membership client."""

from __future__ import annotations

from ..exceptions import DirtyWorkingTreeError
from .context import _Context
from .workflows import WorkflowClient


class BranchClient:
    """Contained-branch membership operations."""

    def __init__(self, context: _Context) -> None:
        self._context = context

    def add_branches(self, *branches: str) -> None:
        """Add branches to the current metabranch."""
        self.update_branches(added=branches)

    def remove_branches(self, *branches: str) -> None:
        """Remove branches from the current metabranch."""
        self.update_branches(removed=branches)

    def update_branches(
        self,
        *,
        added: tuple[str, ...] = (),
        removed: tuple[str, ...] = (),
    ) -> None:
        """Apply a net branch membership update to the current metabranch."""
        self._context.ensure_no_active_workflow()
        added = tuple(dict.fromkeys(added))
        removed = tuple(dict.fromkeys(removed))
        definition = self._context.load_definition()
        updated = self._context.with_validated_branch_updates(
            definition,
            added=added,
            removed=removed,
        )
        if updated == definition:
            return
        if self._context.git_client.is_dirty():
            raise DirtyWorkingTreeError(
                "Working tree has local changes; changing contained branches rebuilds the metabranch, so commit, stash, or discard them first."
            )
        with self._context.operation_lock(
            "branch:update", metabranch_name=definition.name
        ):
            self._context.save_definition(updated)
        WorkflowClient(self._context).rebase()
