# Copyright 2026 Guildhouse Dev
# SPDX-License-Identifier: Apache-2.0

"""Bascule connector — governed shell sessions via Shellstream.

The Bascule connector uses the AC as the credential.  Bascule (the
governed-shell runtime) validates ACs natively — no separate secrets
backend is needed.  The transport establishes a Shellstream session
to the target endpoint via a Bascule proxy.

Real integration:
  The ``BasculeTransport`` will use the Shellstream protocol library
  (``substrate/shellstream/``) to establish a 3-way attested handshake
  with the target.  The SAT (Shell Attestation Token) embedded in the
  Shellstream frame header is derived from the AC.  See
  ``SS-SPEC-0001 — Shellstream Protocol.md`` for the handshake flow.

  Library: ``shellstream-py`` (future) or gRPC to Bascule proxy
  Protocol: Shellstream over TCP / QUIC
  Auth: AC passthrough — the AC IS the credential

Stubbed in this sprint — transport returns placeholder results.
"""

from __future__ import annotations

from typing import Any, Optional

from gsap_broker.connectors.session import SessionConnector, SessionTransport
from gsap_broker.credentials.resolver import Credential, CredentialResolver


class BasculeTransport(SessionTransport):
    """Shellstream transport to a Bascule-governed endpoint.

    Stubbed — actual Shellstream integration in a future sprint.
    """

    transport_id = "bascule"

    def __init__(self) -> None:
        self._target = ""
        self._connected = False

    async def connect(self, target: str, credential: Credential) -> None:
        # TODO: establish Shellstream connection to target via Bascule
        # proxy.  The credential IS the AC (BasculeCredential).
        # Handshake: ATTEST-INIT → ATTEST-VERIFY → ATTEST-CONFIRM.
        self._target = target
        self._connected = True

    async def execute(self, command: str, params: Optional[dict[str, Any]] = None) -> dict[str, Any]:
        # TODO: send command via Shellstream, capture output.
        # Shellstream frames carry the SAT in the header for
        # per-frame attestation.
        if not self._connected:
            raise RuntimeError("Not connected")
        return {
            "stub": True,
            "transport": self.transport_id,
            "target": self._target,
            "command": command,
            "params": params or {},
        }

    async def disconnect(self) -> None:
        self._connected = False

    async def is_alive(self) -> bool:
        return self._connected


class BasculeConnector(SessionConnector):
    """Governed shell connector using Bascule/Shellstream."""

    connector_id = "bascule"
    corpus_entry_cid = "sha256:bascule-connector-v1"
    credential_type = "bascule_ac"
    transport_class = BasculeTransport
    capability_mask = 0x7  # READ | PROPOSE | MUTATE
    declared_endpoints = ["shellstream://*"]
    accord_template = "governed-shell"
    gsap_required = True
    chronicle_enabled = True

    def __init__(self, credential_resolver: CredentialResolver):
        super().__init__(credential_resolver)
