# Copyright (c) 2025 CoReason, Inc.
#
# This software is proprietary and dual-licensed.
# Licensed under the Prosperity Public License 3.0 (the "License").
# A copy of the license is available at https://prosperitylicense.com/versions/3.0.0
# For details, see the LICENSE file.
# Commercial use beyond a 30-day trial requires a separate license.
#
# Source Code: https://github.com/CoReason-AI/coreason_vault

from typing import Any, Dict, Optional, Union

import anyio

from coreason_vault.config import CoreasonVaultConfig
from coreason_vault.exceptions import EncryptionError, SecretNotFoundError, VaultConnectionError
from coreason_vault.manager_async import VaultManagerAsync


class VaultManager:
    """The Sync Facade for VaultManagerAsync.

    Implements the "Async-Native with Sync Facade" pattern.
    """

    def __init__(self, config: Optional[CoreasonVaultConfig] = None):
        """Initializes the VaultManager (Sync Facade).

        Args:
            config (CoreasonVaultConfig): The configuration object for Vault connection and authentication.
        """
        # If config is passed, use it. If not, manager_async handles default.
        self._async = VaultManagerAsync(config)
        self.config = self._async.config

    def __enter__(self) -> "VaultManager":
        return self

    def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
        try:
            anyio.run(self._async.__aexit__, exc_type, exc_val, exc_tb)
        except RuntimeError:
            # Fallback if no loop (should not happen with anyio.run unless nested)
            # anyio.run starts a loop.
            pass

    def get_secret(self, path: str) -> Dict[str, Any]:
        return anyio.run(self._async.get_secret, path)  # type: ignore[no-any-return]

    def get_dynamic_secret(self, path: str) -> Dict[str, Any]:
        return anyio.run(self._async.get_dynamic_secret, path)  # type: ignore[no-any-return]

    def encrypt(self, plaintext: Union[str, bytes], key_name: str, context: Optional[str] = None) -> str:
        return anyio.run(self._async.encrypt, plaintext, key_name, context)  # type: ignore[no-any-return]

    def decrypt(self, ciphertext: str, key_name: str, context: Optional[str] = None) -> Union[str, bytes]:
        return anyio.run(self._async.decrypt, ciphertext, key_name, context)  # type: ignore[no-any-return]


# Export Exceptions for easier access
__all__ = [
    "VaultManager",
    "VaultManagerAsync",
    "CoreasonVaultConfig",
    "SecretNotFoundError",
    "EncryptionError",
    "VaultConnectionError",
]
