#!/usr/bin/env python3
# Copyright (c) Subzero Labs, Inc.
# SPDX-License-Identifier: Apache-2.0

"""
Advanced RPC Methods Example

This example demonstrates the newly added RPC methods in the Python CDK:
- Transaction status checking
- Signature status monitoring
- Epoch information
- Subscription and triggered transaction queries
- Blockhash validation
- Health monitoring
"""

from rialo_py_cdk import (
    generate_keypair,
    Wallet,
    HttpRpcClient,
    PublicKey,
    Hash,
    Signature,
    get_localnet_url,
    RialoException,
)
import time


def advanced_rpc_example():
    """Demonstrate advanced RPC method capabilities."""
    print('🚀 Starting Rialo CDK Advanced RPC Methods Example\n')

    try:
        # 1. Set up wallet and client
        print('1. Setting up wallet and RPC client...')
        keypair = generate_keypair()
        wallet = Wallet('rpc-demo-wallet', keypair, None, None)
        client = HttpRpcClient(get_localnet_url())
        
        wallet_pubkey = PublicKey(wallet.get_public_key().to_bytes())
        print(f'   Wallet public key: {wallet.get_public_key_string()}')
        print(f'   Connected to: {get_localnet_url()}')

        # 2. Get epoch information
        print('\n2. Getting epoch information...')
        try:
            epoch_info = client.get_epoch_info()
            print(f'   Current epoch: {epoch_info["epoch"]}')
            print(f'   Slot index: {epoch_info["slot_index"]}')
            print(f'   Slots in epoch: {epoch_info["slots_in_epoch"]}')
            print(f'   Absolute slot: {epoch_info["absolute_slot"]}')
            print(f'   Block height: {epoch_info["block_height"]}')
            print(f'   Transaction count: {epoch_info["transaction_count"]}')
        except RialoException as e:
            print(f'   ⚠️ Could not get epoch info: {e}')

        # 3. Check blockhash validity
        print('\n3. Testing blockhash validation...')
        try:
            # Test with a hash to see if it's a valid blockhash
            test_hash = Hash(bytes([42] * 32))
            is_valid = client.is_blockhash_valid(test_hash)
            print(f'   Test hash: {test_hash}')
            print(f'   Hash is valid blockhash: {is_valid}')

        except RialoException as e:
            print(f'   ⚠️ Could not validate blockhash: {e}')

        # 4. Health monitoring
        print('\n4. Checking network health...')
        try:
            health_status = client.get_health()
            print(f'   Network health status: {health_status}')
        except RialoException as e:
            print(f'   ⚠️ Could not get health status: {e}')

        # 5. Create and monitor a transaction
        print('\n5. Creating and monitoring transactions...')
        try:
            # Request airdrop to have a transaction to monitor
            print('   Requesting airdrop...')
            airdrop_signature = client.request_airdrop(wallet_pubkey, 1000000)  # 1M kelvin
            print(f'   Airdrop signature: {airdrop_signature}')
            
            # Check signature status
            print('   Checking signature status...')
            signature_statuses = client.get_signature_statuses([airdrop_signature])
            
            if signature_statuses:
                status = signature_statuses[0]
                print(f'   Signature slot: {status.get("slot", "N/A")}')
                print(f'   Is executed: {status.get("executed", "N/A")}')
                print(f'   Error: {status.get("err", "None")}')
                print(f'   Status: {status.get("confirmation_status", "N/A")}')
            else:
                print('   No signature status available')

            # Get transaction details
            print('   Getting transaction details...')
            try:
                transaction_info = client.get_transaction(airdrop_signature)
                print(f'   Transaction slot: {transaction_info.get("slot", "N/A")}')
                print(f'   Block time: {transaction_info.get("block_time", "N/A")}')
            except RialoException as e:
                print(f'   ⚠️ Could not get transaction details: {e}')
                
        except RialoException as e:
            print(f'   ⚠️ Could not create/monitor transaction: {e}')
            print('   (This is normal if network is not running or configured)')

        # 6. Subscription queries (Rialo-specific)
        print('\n6. Testing subscription queries...')
        try:
            subscriptions = client.get_subscriptions(wallet_pubkey, None, 10)
            print(f'   Subscriptions found: {subscriptions.get("subscriptions", 0)}')
            
            # Test triggered transactions
            triggered = client.get_triggered_transactions(wallet_pubkey, 10)
            print(f'   Triggered transactions: {triggered.get("transactions", 0)}')
            
        except RialoException as e:
            print(f'   ⚠️ Subscription queries not available: {e}')
            print('   (These are Rialo-specific features that may not be available)')

        # 7. Demonstrate signature monitoring workflow
        print('\n7. Signature monitoring workflow...')
        
        # Create some mock signatures for demonstration
        mock_signatures = [
            Signature(bytes([i] * 64)) for i in range(1, 4)
        ]
        
        print('   Testing with mock signatures...')
        try:
            statuses = client.get_signature_statuses(mock_signatures)
            print(f'   Checked {len(mock_signatures)} signatures')
            
            for i, status in enumerate(statuses):
                if status.get('slot') is not None:
                    print(f'     Signature {i+1}: Found in slot {status["slot"]}')
                else:
                    print(f'     Signature {i+1}: Not found')
                    
        except RialoException as e:
            print(f'   ⚠️ Could not check mock signatures: {e}')

        # 8. Network statistics and monitoring
        print('\n8. Network statistics and monitoring...')
        try:
            # Get current slot
            current_height = client.get_block_height()
            print(f'   Current slot: {current_height}')
            
            # Get transaction count
            tx_count = client.get_transaction_count()
            print(f'   Total transactions: {tx_count}')
            
            # Calculate transactions per slot (rough estimate)
            if current_height > 0 and tx_count > 0:
                tx_per_slot = tx_count / current_height
                print(f'   Average transactions per slot: {tx_per_slot:.2f}')
                
        except RialoException as e:
            print(f'   ⚠️ Could not get network statistics: {e}')

        # 9. Rent and account size calculations
        print('\n9. Rent and account calculations...')
        try:
            # Test different account sizes
            sizes_to_test = [0, 32, 100, 1000, 10000]
            
            print('   Rent exemption amounts:')
            for size in sizes_to_test:
                min_balance = client.get_minimum_balance_for_rent_exemption(size)
                print(f'     {size:5d} bytes: {min_balance:10d} kelvin')
                
        except RialoException as e:
            print(f'   ⚠️ Could not calculate rent exemption: {e}')

        print('\n✅ Advanced RPC methods demo completed!')
        print('\n📋 Summary of capabilities demonstrated:')
        print('   • Epoch information retrieval')
        print('   • Blockhash validation')
        print('   • Network health monitoring')
        print('   • Transaction status checking')
        print('   • Signature status monitoring')
        print('   • Subscription queries (Rialo-specific)')
        print('   • Network statistics and monitoring')
        print('   • Rent calculation for different account sizes')

    except Exception as error:
        print(f'❌ Error during advanced RPC demo: {error}')
        raise error


def main():
    """Run the advanced RPC methods example."""
    try:
        advanced_rpc_example()
        print('\n🎉 Advanced RPC methods example finished!')
    except Exception as error:
        print(f'\n💥 Example failed: {error}')
        import traceback
        traceback.print_exc()
        exit(1)


if __name__ == "__main__":
    main()