"""Shared Protocol definitions for integrations. Domain-agnostic interfaces."""
from __future__ import annotations
from typing import Optional, Protocol


class GitHubClientProtocol(Protocol):
    """Protocol for GitHub API operations."""

    async def create_repo(self, name: str, private: bool, org: Optional[str] = None) -> "RepoInfo": ...
    async def push_files(
        self, repo: str, branch: str, files: dict[str, str], message: str
    ) -> str: ...
    async def create_commit(
        self, repo: str, branch: str, files: dict[str, str], message: str
    ) -> str: ...
    async def create_pull_request(
        self, repo: str, title: str, head: str, base: str
    ) -> "PRInfo": ...
    async def get_file_contents(self, repo: str, path: str, ref: str) -> bytes: ...
    async def compare_commits(self, repo: str, base: str, head: str) -> "DiffInfo": ...
    async def clone_and_push(
        self, repo: str, source_path: str, branch: str, message: str
    ) -> str: ...


class RepoInfo:
    """GitHub repo info."""

    def __init__(
        self,
        id: int,
        full_name: str,
        clone_url: str,
        default_branch: str,
        html_url: Optional[str] = None,
    ):
        self.id = id
        self.full_name = full_name
        self.clone_url = clone_url
        self.default_branch = default_branch
        self.html_url = html_url


class PRInfo:
    """Pull request info."""

    def __init__(self, number: int, url: str):
        self.number = number
        self.url = url


class DiffInfo:
    """Commit diff info."""

    def __init__(self, files: list[dict], html_url: str):
        self.files = files
        self.html_url = html_url


class EmailProviderProtocol(Protocol):
    """Protocol for email sending."""

    async def send(
        self,
        to: str,
        subject: str,
        html: str,
        text: Optional[str] = None,
        reply_to: Optional[str] = None,
    ) -> "SendResult": ...


class OpsNotifierProtocol(Protocol):
    """Outbound notifications to the internal ops/admin inboxes."""

    async def notify(
        self,
        *,
        subject: str,
        html: str,
        text: str,
        reply_to: Optional[str] = None,
    ) -> None: ...


class SendResult:
    """Email send result."""

    def __init__(self, success: bool, message_id: Optional[str] = None, error: Optional[str] = None):
        self.success = success
        self.message_id = message_id
        self.error = error
