#!/usr/bin/env python3
"""
Bridge Monitor Service
Monitors trustless bridge events and system health
"""

import os
import sys
import time
import json
import logging
from typing import Dict, List, Optional
from datetime import datetime
from web3 import Web3
from web3.middleware import geth_poa_middleware

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

class BridgeMonitor:
    """Main bridge monitoring service"""
    
    def __init__(self, config_path: str = None):
        """Initialize bridge monitor with configuration"""
        self.config = self._load_config(config_path)
        self.chain138_w3 = self._init_web3(self.config['chain138_rpc'])
        self.ethereum_w3 = self._init_web3(self.config['ethereum_rpc'])
        
        # Contract addresses
        self.contracts = self.config.get('contracts', {})
        
        # Event watchers
        self.event_watchers = []
        
        # Metrics
        self.metrics = {
            'deposits': 0,
            'claims': 0,
            'challenges': 0,
            'finalizations': 0,
            'bonds_posted': 0,
            'bonds_slashed': 0,
            'errors': 0
        }
        
    def _load_config(self, config_path: Optional[str]) -> Dict:
        """Load configuration from file or environment"""
        if config_path and os.path.exists(config_path):
            with open(config_path, 'r') as f:
                return json.load(f)
        
        # Load from environment variables
        return {
            'chain138_rpc': os.getenv('CHAIN138_RPC', 'http://192.168.11.250:8545'),
            'ethereum_rpc': os.getenv('ETHEREUM_RPC', 'https://eth.llamarpc.com'),
            'poll_interval': int(os.getenv('POLL_INTERVAL', '12')),  # 12 seconds (block time)
            'contracts': {
                'lockbox138': os.getenv('LOCKBOX138_ADDRESS', ''),
                'inbox_eth': os.getenv('INBOX_ETH_ADDRESS', ''),
                'bond_manager': os.getenv('BOND_MANAGER_ADDRESS', ''),
                'challenge_manager': os.getenv('CHALLENGE_MANAGER_ADDRESS', ''),
                'liquidity_pool': os.getenv('LIQUIDITY_POOL_ADDRESS', '')
            }
        }
    
    def _init_web3(self, rpc_url: str) -> Web3:
        """Initialize Web3 connection"""
        w3 = Web3(Web3.HTTPProvider(rpc_url))
        
        # Add POA middleware if needed (for some networks)
        try:
            w3.middleware_onion.inject(geth_poa_middleware, layer=0)
        except:
            pass
        
        if not w3.is_connected():
            raise ConnectionError(f"Failed to connect to RPC: {rpc_url}")
        
        logger.info(f"Connected to {rpc_url}")
        return w3
    
    def start_monitoring(self):
        """Start monitoring bridge events"""
        logger.info("Starting bridge monitor...")
        
        # Start event watchers
        from event_watcher import EventWatcher
        from alert_manager import AlertManager
        
        alert_manager = AlertManager(self.config.get('alerts', {}))
        
        # Monitor ChainID 138 deposits
        if self.contracts.get('lockbox138'):
            watcher = EventWatcher(
                self.chain138_w3,
                self.contracts['lockbox138'],
                'Deposit',
                alert_manager
            )
            self.event_watchers.append(watcher)
        
        # Monitor Ethereum claims
        if self.contracts.get('inbox_eth'):
            watcher = EventWatcher(
                self.ethereum_w3,
                self.contracts['inbox_eth'],
                'ClaimSubmitted',
                alert_manager
            )
            self.event_watchers.append(watcher)
        
        # Monitor challenges
        if self.contracts.get('challenge_manager'):
            watcher = EventWatcher(
                self.ethereum_w3,
                self.contracts['challenge_manager'],
                'ClaimChallenged',
                alert_manager
            )
            self.event_watchers.append(watcher)
        
        # Start monitoring loop
        self._monitor_loop()
    
    def _monitor_loop(self):
        """Main monitoring loop"""
        poll_interval = self.config.get('poll_interval', 12)
        
        while True:
            try:
                # Check RPC health
                self._check_rpc_health()
                
                # Process events from all watchers
                for watcher in self.event_watchers:
                    watcher.process_events()
                
                # Update metrics
                self._update_metrics()
                
                # Sleep until next poll
                time.sleep(poll_interval)
                
            except KeyboardInterrupt:
                logger.info("Stopping bridge monitor...")
                break
            except Exception as e:
                logger.error(f"Error in monitoring loop: {e}", exc_info=True)
                self.metrics['errors'] += 1
                time.sleep(poll_interval)
    
    def _check_rpc_health(self):
        """Check RPC endpoint health"""
        try:
            chain138_block = self.chain138_w3.eth.block_number
            ethereum_block = self.ethereum_w3.eth.block_number
            logger.debug(f"Chain138 block: {chain138_block}, Ethereum block: {ethereum_block}")
        except Exception as e:
            logger.error(f"RPC health check failed: {e}")
            raise
    
    def _update_metrics(self):
        """Update monitoring metrics"""
        # Export metrics to Prometheus or other monitoring system
        # This is a placeholder - implement actual metrics export
        pass
    
    def get_metrics(self) -> Dict:
        """Get current metrics"""
        return self.metrics.copy()


def main():
    """Main entry point"""
    config_path = os.getenv('BRIDGE_MONITOR_CONFIG', None)
    monitor = BridgeMonitor(config_path)
    monitor.start_monitoring()


if __name__ == '__main__':
    main()

