# Copyright (c) Subzero Labs, Inc.
# SPDX-License-Identifier: Apache-2.0

"""
Rialo Python CDK

A comprehensive Python library for interacting with the Rialo blockchain.
This package provides wallet management, transaction building, RPC communication,
and program deployment capabilities.

Example:
    >>> from rialo_py_cdk import Wallet, HttpRpcClient, TransactionBuilder
    >>> from rialo_py_cdk import generate_keypair
    >>> 
    >>> # Generate a new keypair
    >>> keypair = generate_keypair()
    >>> 
    >>> # Create a wallet
    >>> wallet = Wallet("my_wallet", keypair)
    >>> 
    >>> # Connect to localnet
    >>> client = HttpRpcClient(get_localnet_url())
"""

import importlib.metadata
from typing import List, Optional, Tuple, Union, Any, Dict
import asyncio

# Import the Rust extension module
# Note: PyO3 exports classes under their #[pyclass(name = "...")] Python names,
# not their Rust struct names. So we import using the Python names.
from rialo_py_cdk._rialo_py_cdk import (
    # Core types (these use their Rust names as Python names via PyO3)
    PyHash as Hash,
    PyPublicKey as PublicKey,
    PySignature as Signature,
    PyAccountMeta as AccountMeta,
    PyInstruction as Instruction,
    # Keyring types (new terminology) - exported with Python names
    DerivedKeypair as _PyDerivedKeypair,
    Keyring as _PyKeyring,
    InMemoryKeyringProvider as _PyInMemoryKeyringProvider,
    # Wallet types (deprecated, for backward compatibility) - exported with Python names
    Account as _PyAccount,
    Wallet as _PyWallet,
    InMemoryWalletProvider as _PyInMemoryWalletProvider,
    # RPC types
    PyHttpRpcClient as _PyHttpRpcClient,
    # Transaction types
    PyTransactionBuilder as TransactionBuilder,
    # Program management types
    PyProgramDeployment as _PyProgramDeployment,
    PyProgramInvocation as _PyProgramInvocation,
    PyLoaderType as LoaderType,
    # Configuration types
    PyConfig as _PyConfig,
    FILE_STORAGE_AVAILABLE,
    KELVIN_PER_RLO,
    # Utility functions
    generate_keypair,
    keypair_from_seed,
    keypair_from_mnemonic,
    generate_mnemonic,
    keypair_from_file,
    public_key_from_keypair,
    sign,
    verify,
    transfer_instruction,
    rlo_to_kelvin,
    kelvin_to_rlo,
    create_wallet_with_mnemonic,
    recover_wallet_from_mnemonic as _recover_wallet_from_mnemonic,
    airdrop_rlo,
    # Network management
    get_rpc_url_for_network,
    list_available_networks,
    # Constants
    get_localnet_url,
    get_default_num_accounts,
    get_kelvin_per_rlo,
    # Exception
    RialoException,
)

# Import file keyring/wallet providers if available
if FILE_STORAGE_AVAILABLE:
    from rialo_py_cdk._rialo_py_cdk import FileKeyringProvider as _PyFileKeyringProvider
    from rialo_py_cdk._rialo_py_cdk import FileWalletProvider as _PyFileWalletProvider

# Import the generated typed RPC client (spec-driven, with typed returns)
from .generated.client import RialoRPCClient  # noqa: F401

__version__ = importlib.metadata.version("rialo-py-cdk")

__all__ = [
    # Core types
    "Hash",
    "PublicKey",
    "Signature",
    # Keyring types (new terminology)
    "DerivedKeypair",
    "Keyring",
    "InMemoryKeyringProvider",
    "FileKeyringProvider",
    # Wallet types (deprecated, for backward compatibility)
    "Account",
    "Wallet",
    "InMemoryWalletProvider",
    "FileWalletProvider",
    # Transaction types
    "AccountMeta",
    "Instruction",
    "TransactionBuilder",
    # Program management types
    "ProgramDeployment",
    "ProgramInvocation",
    "LoaderType",
    # Configuration types
    "Config",
    # RPC types
    "RialoRPCClient",
    "HttpRpcClient",
    # Utility functions
    "generate_keypair",
    "keypair_from_seed",
    "keypair_from_mnemonic",
    "generate_mnemonic",
    "keypair_from_file",
    "public_key_from_keypair",
    "sign",
    "verify",
    "transfer_instruction",
    "rlo_to_kelvin",
    "kelvin_to_rlo",
    "create_wallet_with_mnemonic",
    "airdrop_rlo",
    # Network management
    "get_rpc_url_for_network",
    "list_available_networks",
    # Constants
    "get_localnet_url",
    "get_default_num_accounts",
    "get_kelvin_per_rlo",
    "KELVIN_PER_RLO",
    # Exception
    "RialoException",
]

# Python wrapper classes for better ergonomics

# Use the Rust types directly - new keyring terminology
DerivedKeypair = _PyDerivedKeypair
Keyring = _PyKeyring
InMemoryKeyringProvider = _PyInMemoryKeyringProvider

# Deprecated wallet types for backward compatibility
Account = _PyAccount
Wallet = _PyWallet
InMemoryWalletProvider = _PyInMemoryWalletProvider

# Common types — RialoRPCClient is the spec-driven typed client (primary),
# HttpRpcClient is the raw PyO3 transport (for advanced/low-level use).
HttpRpcClient = _PyHttpRpcClient
ProgramDeployment = _PyProgramDeployment
ProgramInvocation = _PyProgramInvocation
Config = _PyConfig

if FILE_STORAGE_AVAILABLE:
    FileKeyringProvider = _PyFileKeyringProvider
    FileWalletProvider = _PyFileWalletProvider
else:
    # Provide stubs if file storage is not available
    class FileKeyringProvider:
        """File-based keyring provider (not available - requires file-storage feature)"""
        
        def __init__(self, base_dir: str):
            raise RuntimeError("FileKeyringProvider requires the file-storage feature to be enabled")
    
    class FileWalletProvider:
        """File-based wallet provider (not available - requires file-storage feature)"""
        
        def __init__(self, base_dir: str):
            raise RuntimeError("FileWalletProvider requires the file-storage feature to be enabled")

# Additional convenience functions

def recover_wallet_from_mnemonic(name: str, mnemonic_phrase: str, passphrase: Optional[str] = None) -> Wallet:
    """
    Recover a wallet from a mnemonic phrase.
    
    This function recovers a wallet from a BIP39 mnemonic phrase. It supports both
    the standard 12-word and 24-word mnemonic formats with optional passphrase.
    
    Args:
        name: The name for the recovered wallet
        mnemonic_phrase: The BIP39 mnemonic phrase (12 or 24 words)
        passphrase: Optional BIP39 passphrase for additional security
        
    Returns:
        The recovered wallet with the derived keypair
        
    Raises:
        RialoException: If the mnemonic phrase is invalid or derivation fails
        
    Example:
        >>> # Recover from a standard 12-word mnemonic
        >>> mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
        >>> wallet = recover_wallet_from_mnemonic("recovered_wallet", mnemonic)
        >>> 
        >>> # Recover with passphrase
        >>> wallet_with_passphrase = recover_wallet_from_mnemonic("secure_wallet", mnemonic, "my_passphrase")
    """
    # Use the Rust implementation directly for better performance and consistency
    if passphrase is None:
        return _recover_wallet_from_mnemonic(name, mnemonic_phrase)
    else:
        # For passphrase support, use the Python implementation until Rust function supports it
        keypair = keypair_from_mnemonic(mnemonic_phrase, passphrase)
        return Wallet(name, keypair, mnemonic_phrase)


# Network configuration helpers

class Networks:
    """Network configuration constants"""
    LOCALHOST = get_localnet_url()

# Units and conversions (use the ones from Rust for consistency)