"""Credential store abstraction for managing API keys and secrets across MCP servers."""

from __future__ import annotations

import logging
import os
from abc import ABC, abstractmethod

logger = logging.getLogger(__name__)


class CredentialStore(ABC):
    """Abstract base for credential storage backends."""

    @abstractmethod
    async def get(self, key: str) -> str | None:
        """Get a credential value by key."""
        ...

    @abstractmethod
    async def set(self, key: str, value: str) -> None:
        """Store a credential."""
        ...

    @abstractmethod
    async def delete(self, key: str) -> bool:
        """Delete a credential. Returns True if it existed."""
        ...

    @abstractmethod
    async def list_keys(self) -> list[str]:
        """List all stored credential keys."""
        ...


class EnvironmentStore(CredentialStore):
    """Credential store backed by environment variables."""

    async def get(self, key: str) -> str | None:
        return os.environ.get(key)

    async def set(self, key: str, value: str) -> None:
        os.environ[key] = value

    async def delete(self, key: str) -> bool:
        if key in os.environ:
            del os.environ[key]
            return True
        return False

    async def list_keys(self) -> list[str]:
        # Only return keys that look like API keys or secrets
        return [k for k in os.environ if any(s in k.upper() for s in ("API_KEY", "SECRET", "TOKEN", "PASSWORD"))]


class MemoryStore(CredentialStore):
    """In-memory credential store (not persisted across restarts)."""

    def __init__(self):
        self._store: dict[str, str] = {}

    async def get(self, key: str) -> str | None:
        return self._store.get(key)

    async def set(self, key: str, value: str) -> None:
        self._store[key] = value

    async def delete(self, key: str) -> bool:
        if key in self._store:
            del self._store[key]
            return True
        return False

    async def list_keys(self) -> list[str]:
        return list(self._store.keys())


class CompositeStore(CredentialStore):
    """
    Composite store that checks multiple backends in order.

    Reads cascade through backends (first match wins).
    Writes go to the first (primary) backend.
    """

    def __init__(self, stores: list[CredentialStore]):
        if not stores:
            raise ValueError("At least one store is required")
        self._stores = stores

    async def get(self, key: str) -> str | None:
        for store in self._stores:
            value = await store.get(key)
            if value is not None:
                return value
        return None

    async def set(self, key: str, value: str) -> None:
        # Write to the primary (first) store
        await self._stores[0].set(key, value)

    async def delete(self, key: str) -> bool:
        # Delete from the primary store
        return await self._stores[0].delete(key)

    async def list_keys(self) -> list[str]:
        all_keys = set()
        for store in self._stores:
            all_keys.update(await store.list_keys())
        return sorted(all_keys)


def create_default_store() -> CredentialStore:
    """Create the default credential store chain: Memory -> Environment."""
    return CompositeStore([MemoryStore(), EnvironmentStore()])
