"""
Windows Credential Manager backend.

Stores secrets in Windows Credential Manager via the keyring library.
Included with g-gremlin.

Target name format: g-gremlin/{integration}/{profile}
"""

from __future__ import annotations

import platform
from typing import List, Optional, Tuple, TYPE_CHECKING

from g_gremlin.credentials.models import (
    INTEGRATION_REGISTRY,
    SecretSource,
    SecretValue,
)

if TYPE_CHECKING:
    import keyring as keyring_module


class WindowsCredentialBackend:
    """
    Backend for Windows Credential Manager via keyring library.

    Target name format: g-gremlin/{integration}/{profile}
    """

    SERVICE_PREFIX = "g-gremlin"

    def __init__(self) -> None:
        self._keyring: Optional[keyring_module] = None
        self._available: Optional[bool] = None

    @property
    def source(self) -> SecretSource:
        return SecretSource.KEYCHAIN  # Reuse KEYCHAIN enum for OS credential stores

    @property
    def is_available(self) -> bool:
        """Check if Windows Credential Manager is available."""
        if self._available is not None:
            return self._available

        if platform.system() != "Windows":
            self._available = False
            return False

        try:
            import keyring
            self._keyring = keyring
            self._available = True
        except ImportError:
            self._available = False
        except Exception:
            self._available = False

        return self._available

    @property
    def is_read_only(self) -> bool:
        return False

    def _service_name(self, integration: str, profile: str) -> str:
        """Build service name for credential entry."""
        return f"{self.SERVICE_PREFIX}/{integration}/{profile}"

    def get_secret(
        self,
        integration: str,
        key: str,
        profile: str = "default",
    ) -> Optional[SecretValue]:
        """Get secret from Windows Credential Manager."""
        if not self.is_available or self._keyring is None:
            return None

        service = self._service_name(integration, profile)
        try:
            value = self._keyring.get_password(service, key)
        except Exception:
            return None

        if value is None:
            return None

        return SecretValue(
            value=value,
            source=SecretSource.KEYCHAIN,
            integration=integration,
            key=key,
            profile=profile,
        )

    def set_secret(
        self,
        integration: str,
        key: str,
        value: str,
        profile: str = "default",
    ) -> None:
        """Store secret in Windows Credential Manager."""
        if not self.is_available or self._keyring is None:
            from g_gremlin.credentials.provider import BackendUnavailableError
            raise BackendUnavailableError(
                "Windows Credential Manager not available. "
                "Ensure you are on Windows with Credential Manager available."
            )

        service = self._service_name(integration, profile)
        self._keyring.set_password(service, key, value)

    def delete_secret(
        self,
        integration: str,
        key: str,
        profile: str = "default",
    ) -> bool:
        """Delete secret from Windows Credential Manager."""
        if not self.is_available or self._keyring is None:
            return False

        service = self._service_name(integration, profile)
        try:
            self._keyring.delete_password(service, key)
            return True
        except Exception:
            return False

    def list_secrets(
        self,
        integration: Optional[str] = None,
        profile: str = "default",
    ) -> List[Tuple[str, str]]:
        """
        List secrets in credential manager.

        Note: keyring doesn't have a list API; we check known keys.
        """
        if not self.is_available:
            return []

        found: List[Tuple[str, str]] = []

        if integration:
            specs = [INTEGRATION_REGISTRY[integration]] if integration in INTEGRATION_REGISTRY else []
        else:
            specs = list(INTEGRATION_REGISTRY.values())

        for spec in specs:
            for key in spec.get_all_keys():
                if self.get_secret(spec.name, key, profile) is not None:
                    found.append((spec.name, key))

        return found
