#!/usr/bin/env python3
"""
Synor Crypto SDK Examples for Python

Demonstrates quantum-resistant cryptographic operations including:
- Hybrid Ed25519 + Dilithium3 signatures
- BIP-39 mnemonic generation and validation
- Post-quantum algorithms (Falcon, SPHINCS+)
- Key derivation functions
"""

import asyncio
import os
from synor_crypto import (
    SynorCrypto,
    CryptoConfig,
    Network,
    FalconVariant,
    SphincsVariant,
    DerivationConfig,
    PasswordDerivationConfig,
    DerivationPath,
)


async def main():
    """Main entry point."""
    # Initialize client
    config = CryptoConfig(
        api_key=os.environ.get("SYNOR_API_KEY", "your-api-key"),
        endpoint="https://crypto.synor.io/v1",
        timeout=30000,
        retries=3,
        debug=False,
        default_network=Network.MAINNET,
    )

    crypto = SynorCrypto(config)

    try:
        # Check service health
        healthy = await crypto.health_check()
        print(f"Service healthy: {healthy}\n")

        # Example 1: Mnemonic operations
        await mnemonic_example(crypto)

        # Example 2: Keypair generation
        await keypair_example(crypto)

        # Example 3: Hybrid signing
        await signing_example(crypto)

        # Example 4: Falcon post-quantum signatures
        await falcon_example(crypto)

        # Example 5: SPHINCS+ post-quantum signatures
        await sphincs_example(crypto)

        # Example 6: Key derivation
        await kdf_example(crypto)

        # Example 7: Hashing
        await hash_example(crypto)
    finally:
        await crypto.close()


async def mnemonic_example(crypto: SynorCrypto):
    """Mnemonic generation and validation."""
    print("=== Mnemonic Operations ===")

    # Generate a 24-word mnemonic (256-bit entropy)
    mnemonic = await crypto.mnemonic.generate(24)
    print(f"Generated mnemonic: {mnemonic.phrase}")
    print(f"Word count: {mnemonic.word_count}")

    # Validate a mnemonic
    validation = await crypto.mnemonic.validate(mnemonic.phrase)
    print(f"Valid: {validation.valid}")
    if not validation.valid:
        print(f"Error: {validation.error}")

    # Convert mnemonic to seed
    seed = await crypto.mnemonic.to_seed(mnemonic.phrase, "optional-passphrase")
    print(f"Seed (hex): {seed.hex()[:32]}...")

    # Word suggestions for autocomplete
    suggestions = await crypto.mnemonic.suggest_words("aban", 5)
    print(f"Suggestions for 'aban': {', '.join(suggestions)}")

    print()


async def keypair_example(crypto: SynorCrypto):
    """Keypair generation and address derivation."""
    print("=== Keypair Operations ===")

    # Generate a random keypair
    keypair = await crypto.keypairs.generate()
    print("Generated hybrid keypair:")
    print(f"  Ed25519 public key size: {len(keypair.public_key.ed25519_bytes)} bytes")
    print(f"  Dilithium public key size: {len(keypair.public_key.dilithium_bytes)} bytes")
    print(f"  Total public key size: {keypair.public_key.size} bytes")

    # Get addresses for different networks
    print("\nAddresses:")
    print(f"  Mainnet: {keypair.get_address(Network.MAINNET)}")
    print(f"  Testnet: {keypair.get_address(Network.TESTNET)}")
    print(f"  Devnet: {keypair.get_address(Network.DEVNET)}")

    # Create keypair from mnemonic (deterministic)
    mnemonic = await crypto.mnemonic.generate(24)
    keypair2 = await crypto.keypairs.from_mnemonic(mnemonic.phrase, "")
    print(f"\nKeypair from mnemonic: {keypair2.get_address(Network.MAINNET)[:20]}...")

    # Derive child keypair using BIP-44 path
    path = DerivationPath.external(0, 0)  # m/44'/21337'/0'/0/0
    print(f"Derivation path: {path}")

    print()


async def signing_example(crypto: SynorCrypto):
    """Hybrid signature operations (Ed25519 + Dilithium3)."""
    print("=== Hybrid Signing ===")

    # Generate keypair
    keypair = await crypto.keypairs.generate()

    # Sign a message
    message = b"Hello, quantum-resistant world!"
    signature = await crypto.signing.sign(keypair, message)

    print("Signature created:")
    print(f"  Ed25519 component: {len(signature.ed25519_bytes)} bytes")
    print(f"  Dilithium component: {len(signature.dilithium_bytes)} bytes")
    print(f"  Total signature size: {signature.size} bytes")

    # Verify the signature
    valid = await crypto.signing.verify(keypair.public_key, message, signature)
    print(f"\nVerification result: {valid}")

    # Verify with tampered message fails
    tampered_message = b"Hello, tampered message!"
    invalid_result = await crypto.signing.verify(
        keypair.public_key, tampered_message, signature
    )
    print(f"Tampered message verification: {invalid_result}")

    print()


async def falcon_example(crypto: SynorCrypto):
    """Falcon post-quantum signature example."""
    print("=== Falcon Post-Quantum Signatures ===")

    # Generate Falcon-512 keypair (128-bit security)
    falcon512 = await crypto.falcon.generate(FalconVariant.FALCON512)
    print("Falcon-512 keypair:")
    print(f"  Public key: {len(falcon512.public_key.key_bytes)} bytes")
    print(f"  Security level: 128-bit")

    # Generate Falcon-1024 keypair (256-bit security)
    falcon1024 = await crypto.falcon.generate(FalconVariant.FALCON1024)
    print("\nFalcon-1024 keypair:")
    print(f"  Public key: {len(falcon1024.public_key.key_bytes)} bytes")
    print(f"  Security level: 256-bit")

    # Sign with Falcon-512
    message = b"Post-quantum secure message"
    signature = await crypto.falcon.sign(falcon512, message)
    print(f"\nFalcon-512 signature: {len(signature.signature_bytes)} bytes")

    # Verify
    valid = await crypto.falcon.verify(
        falcon512.public_key.key_bytes, message, signature
    )
    print(f"Verification: {valid}")

    print()


async def sphincs_example(crypto: SynorCrypto):
    """SPHINCS+ post-quantum signature example (hash-based)."""
    print("=== SPHINCS+ Hash-Based Signatures ===")

    # SPHINCS+ variants with different security levels
    variants = [
        (SphincsVariant.SHAKE128S, 128, 7856),
        (SphincsVariant.SHAKE192S, 192, 16224),
        (SphincsVariant.SHAKE256S, 256, 29792),
    ]

    # Generate and demonstrate each variant
    for variant, security, sig_size in variants:
        keypair = await crypto.sphincs.generate(variant)
        print(f"SPHINCS+ {variant.value}:")
        print(f"  Security level: {security}-bit")
        print(f"  Expected signature size: {sig_size} bytes")

        # Sign a message
        message = b"Hash-based quantum security"
        signature = await crypto.sphincs.sign(keypair, message)
        print(f"  Actual signature size: {len(signature.signature_bytes)} bytes")

        # Verify
        valid = await crypto.sphincs.verify(
            keypair.public_key.key_bytes, message, signature
        )
        print(f"  Verification: {valid}\n")


async def kdf_example(crypto: SynorCrypto):
    """Key derivation functions."""
    print("=== Key Derivation Functions ===")

    # HKDF (HMAC-based Key Derivation Function)
    seed = b"master-secret-key-material-here"
    hkdf_config = DerivationConfig(
        salt=b"application-salt",
        info=b"encryption-key",
        output_length=32,
    )

    derived_key = await crypto.kdf.derive_key(seed, hkdf_config)
    print(f"HKDF derived key: {derived_key.hex()}")

    # PBKDF2 (Password-Based Key Derivation Function)
    password = b"user-password"
    pbkdf2_config = PasswordDerivationConfig(
        salt=b"random-salt-value",
        iterations=100000,
        output_length=32,
    )

    password_key = await crypto.kdf.derive_from_password(password, pbkdf2_config)
    print(f"PBKDF2 derived key: {password_key.hex()}")

    print()


async def hash_example(crypto: SynorCrypto):
    """Cryptographic hash functions."""
    print("=== Hash Functions ===")

    data = b"Data to hash"

    # SHA3-256 (FIPS 202)
    sha3 = await crypto.hash.sha3_256(data)
    print(f"SHA3-256: {sha3.hex}")

    # BLAKE3 (fast, parallel)
    blake3 = await crypto.hash.blake3(data)
    print(f"BLAKE3:   {blake3.hex}")

    # Keccak-256 (Ethereum compatible)
    keccak = await crypto.hash.keccak256(data)
    print(f"Keccak:   {keccak.hex}")

    print()


if __name__ == "__main__":
    asyncio.run(main())
