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

"""PowerShell connector — WinRM/PSRP sessions to Windows endpoints.

Uses Kerberos credentials from the CredentialResolver (acquired via
Entra cloud trust or on-prem KDC) to establish a PSRP (PowerShell
Remoting Protocol) session over WinRM/HTTPS.

Real integration:
  Library: ``pypsrp`` (well-maintained PSRP client)
  Protocol: PSRP over WinRM (HTTPS port 5986)
  Auth: Kerberos (from ``KerberosCredential``) or CredSSP
  Output: Structured PSObject results deserialized to dicts

  The transport will:
  1. Create a ``pypsrp.wsman.WSMan`` connection with the Kerberos
     ticket from the credential.
  2. Open a ``pypsrp.powershell.PowerShell`` runspace.
  3. Execute commands via ``ps.add_script(command).invoke()``.
  4. Return deserialized PSObject results as Python dicts.
  5. Close the runspace and WSMan connection on disconnect.

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 PowerShellTransport(SessionTransport):
    """PSRP transport over WinRM/HTTPS.

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

    transport_id = "psrp"

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

    async def connect(self, target: str, credential: Credential) -> None:
        # TODO: create pypsrp.wsman.WSMan with Kerberos auth from
        # credential.ticket.  Target format: hostname:5986.
        self._target = target
        self._connected = True

    async def execute(self, command: str, params: Optional[dict[str, Any]] = None) -> dict[str, Any]:
        # TODO: execute PowerShell command via PSRP.
        # ps = PowerShell(wsman); ps.add_script(command).invoke()
        # Return structured PSObject results as dicts.
        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 PowerShellConnector(SessionConnector):
    """Windows management via PowerShell Remoting."""

    connector_id = "powershell"
    corpus_entry_cid = "sha256:powershell-connector-v1"
    credential_type = "kerberos"
    transport_class = PowerShellTransport
    capability_mask = 0x7  # READ | PROPOSE | MUTATE
    declared_endpoints = ["wsman://*:5986"]
    accord_template = "windows-management"
    gsap_required = True
    chronicle_enabled = True

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