import asyncio
import logging
import os
import json
import time
import websockets
import torch
from typing import Optional, Dict, Tuple
from decimal import Decimal
import base64
import subprocess
import psutil

# Import all your existing components
from solana_cli import SolanaCLI
from solana_rust_bot import TradingCore, TradeParams
from gpu_accelerator import GPUAccelerator, AcceleratorConfig
from vector_store import EnhancedVectorStore
from price_impact import EnhancedImpactCalculator
from mev_protection import MevProtection, MevConfig
from system_manager import SystemManager
from price_monitor import RaydiumMonitor
from advanced_trading import AdvancedTrading
from mempool_analyzer import EnhancedMempoolAnalyzer

# Enhanced logging configuration
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s.%(msecs)03d [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s',
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler(f'trading_{time.strftime("%Y%m%d_%H%M%S")}.log')
    ]
)
logger = logging.getLogger(__name__)

[Your existing BalanceManager class here]
[Your existing PositionManager class here]
[Your existing RaydiumTrader class here]

async def main():
    try:
        # Initialize accelerator with optimized config
        accelerator_config = AcceleratorConfig(
            batch_size=1024,
            matrix_size=2048,
            use_amp=True,
            memory_fraction=0.8,
            cpu_workers=16,
            cpu_batch_size=256,
            min_profit_pct=1.5,
            max_profit_pct=4.0,
            min_input_sol=0.005,
            max_input_sol=0.05,
            slippage=0.003,
            wsol_target_ratio=0.6,
            sol_target_ratio=0.4
        )
        
        # Create and initialize accelerator
        accelerator = GPUAccelerator(accelerator_config)
        logger.info(f"Initialized GPU accelerator: {torch.cuda.get_device_name()}")
        
        # Initialize trader with accelerator
        trader = RaydiumTrader('config.json')
        trader.gpu_accelerator = accelerator
        
        # Start trading system
        await trader.start()
        
    except Exception as e:
        logger.error(f"Fatal error in trading system: {e}", exc_info=True)
    finally:
        if 'trader' in locals():
            await trader.cleanup()

if __name__ == "__main__":
    # Configure GPU settings
    torch.cuda.set_device(0)
    torch.backends.cuda.matmul.allow_tf32 = True
    torch.backends.cudnn.benchmark = True
    
    # Enhanced system information logging
    logger.info("System Information:")
    logger.info(f"PyTorch Version: {torch.__version__}")
    logger.info(f"CUDA Version: {torch.version.cuda}")
    logger.info(f"GPU Device: {torch.cuda.get_device_name()}")
    logger.info(f"CPU Cores: {psutil.cpu_count(logical=False)}")
    logger.info(f"Total Memory: {psutil.virtual_memory().total / (1024**3):.2f} GB")
    
    # Initialize and run the trading system
    asyncio.run(main())
  this stuff needs to go inside of this script i think so  import asyncio
import logging
import os
import json
import time
import websockets
import torch
from typing import Optional, Dict, Tuple
from decimal import Decimal
import base64
import subprocess

# Import necessary components
from solana_cli import SolanaCLI
from solana_rust_bot import TradingCore, TradeParams
from gpu_accelerator import GPUAccelerator, AcceleratorConfig
from vector_store import EnhancedVectorStore
from price_impact import EnhancedImpactCalculator
from mev_protection import MevProtection, MevConfig
from system_manager import SystemManager
from price_monitor import RaydiumMonitor
from advanced_trading import AdvancedTrading
from mempool_analyzer import EnhancedMempoolAnalyzer
# Setup logging
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s.%(msecs)03d [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s',
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler(f'trading_{time.strftime("%Y%m%d_%H%M%S")}.log')
    ]
)
logger = logging.getLogger(__name__)

# BalanceManager
class BalanceManager:
    def __init__(self, config: Dict, trader: TradingCore):
        logger.debug("Initializing BalanceManager")
        self.config = config
        self.trader = trader
        self.wsol_target = config['trading']['balance_management']['wsol_target_ratio']
        self.sol_target = config['trading']['balance_management']['sol_target_ratio']
        self.rebalance_threshold = config['trading']['balance_management']['rebalance_threshold']
        self.min_rebalance_amount = config['trading']['balance_management']['min_rebalance_amount']
        self.last_rebalance = 0
        self.rebalance_cooldown = 60

    async def check_balances(self) -> Tuple[float, float]:
        try:
            sol_balance = float(self.trader.get_balance())
            wsol_balance = float(self.trader.get_wsol_balance())
            logger.debug(f"Checked balances - SOL: {sol_balance}, WSOL: {wsol_balance}")
            return sol_balance, wsol_balance
        except Exception as e:
            logger.error(f"Balance check error: {e}")
            return 0.0, 0.0

    async def rebalance_if_needed(self) -> bool:
        try:
            if time.time() - self.last_rebalance < self.rebalance_cooldown:
                logger.debug("Rebalance cooldown in effect")
                return False

            sol_balance, wsol_balance = await self.check_balances()
            total_balance = sol_balance + wsol_balance

            if total_balance == 0:
                logger.warning("No total balance to rebalance")
                return False

            current_wsol_ratio = wsol_balance / total_balance
            wsol_deviation = abs(current_wsol_ratio - self.wsol_target)

            if wsol_deviation > self.rebalance_threshold:
                target_wsol = total_balance * self.wsol_target
                
                if wsol_balance < target_wsol:
                    wrap_amount = target_wsol - wsol_balance
                    if wrap_amount >= self.min_rebalance_amount:
                        logger.info(f"Rebalancing: Wrapping {wrap_amount:.6f} SOL to WSOL")
                        result = self.trader.transfer_to_wsol(float(wrap_amount))
                        if result:
                            self.last_rebalance = time.time()
                            logger.info("Successfully rebalanced WSOL")
                            return True

            logger.debug("No rebalancing needed")
            return False

        except Exception as e:
            logger.error(f"Rebalance error: {e}")
            return False

# PositionManager
class PositionManager:
    def __init__(self, config: Dict):
        logger.debug("Initializing PositionManager")
        self.config = config
        self.current_size = config['trading']['position']['initial_size']
        self.max_size = config['trading']['position']['max_size']
        self.size_increment = config['trading']['position']['scale_increment']
        self.success_threshold = config['trading']['position']['success_threshold']
        self.successful_trades = 0
        self.total_profit = Decimal('0')

    def get_position_size(self) -> float:
        return float(self.current_size)

    def update_metrics(self, profit: Decimal, success: bool):
        logger.debug(f"Updating metrics - Profit: {profit}, Success: {success}")
        if success:
            self.successful_trades += 1
            self.total_profit += profit

            if self.successful_trades % self.success_threshold == 0:
                new_size = min(self.current_size + self.size_increment, self.max_size)
                if new_size != self.current_size:
                    logger.info(f"Scaling up position size: {self.current_size:.6f} -> {new_size:.6f}")
                    self.current_size = new_size
        else:
            self.successful_trades = 0

# RaydiumTrader
class RaydiumTrader:
    def __init__(self, config_path: str):
        logger.debug("Initializing RaydiumTrader")
        
        try:
            with open(config_path, 'r') as f:
                self.config = json.load(f)
            logger.info("Configuration loaded successfully.")
        except Exception as e:
            logger.error(f"Error loading configuration: {e}", exc_info=True)
            raise

        self.active = False
        self.last_trade_time = 0
        self.trade_count = 0
        self.balance_manager = None
        self.position_manager = None
        self.vector_store = None
        self.impact_calculator = None
        self.mempool_analyzer = None
        self.system = None
        self.price_monitor = None
        self.trading_core = None
        self.gpu_accelerator = None
        logger.info("Raydium trader initialized")

    async def initialize(self) -> bool:
        logger.info("Starting system initialization...")
        try:
            await self._initialize_components()
            await self._log_initial_balances()
            self.active = True
            logger.info("RaydiumTrader is now active.")
            return True
        except Exception as e:
            logger.error(f"Initialization error: {e}", exc_info=True)
            return False

    async def _initialize_components(self):
        logger.debug("Initializing system components...")
        
        self.system = SystemManager()
        await self.system.start()
        logger.info("System manager started successfully.")

        gpu_config = AcceleratorConfig()
        self.gpu_accelerator = GPUAccelerator(gpu_config)
        logger.info("GPU accelerator initialized successfully.")

        self.vector_store = EnhancedVectorStore(self.config)

        # Initialize trading core BEFORE impact calculator
        trading_config = {
            "compute_limit": self.config['execution']['compute_limit'],
            "priority_fee": self.config['execution']['priority_fee'],
            "max_priority_fee": self.config['execution']['max_priority_fee'],
            "slippage": self.config['execution']['slippage'],
            "retry_count": self.config['execution']['retry_count'],
            "position_size": self.config['trading']['position']['initial_size'],
            "max_position_size": self.config['trading']['position']['max_size'],
            "gas_reserve": self.config['trading']['position']['gas_reserve']
        }

        self.trading_core = TradingCore(
            secret_key=os.environ['SOLANA_PRIVATE_KEY'],
            rpc_url=self.config['rpc']['helius']['endpoint'],
            config_json=json.dumps(trading_config)
        )
        logger.info("Trading core initialized successfully.")

        # Now initialize impact calculator with trading_core
        self.impact_calculator = EnhancedImpactCalculator(self.config, self.trading_core)
        self.mempool_analyzer = EnhancedMempoolAnalyzer(self.config)

        self.balance_manager = BalanceManager(self.config, self.trading_core)
        self.position_manager = PositionManager(self.config)

        pool_data = self.config['accounts']['sol_wsol']
        self.trading_core.update_pool(pool_data)
    async def _log_initial_balances(self):
        logger.debug("Logging initial SOL and WSOL balances")
        sol_balance = self.trading_core.get_balance()
        wsol_balance = self.trading_core.get_wsol_balance()
        logger.info(f"Initial Balances: SOL={sol_balance}, WSOL={wsol_balance}")

    async def monitor_mempool(self):
        """Monitor mempool for opportunities"""
        logger.info("Starting mempool monitoring...")
        
        while self.active:
            try:
                async with websockets.connect(
                    self.config['rpc']['helius']['websocket'],
                    ping_interval=30,
                    ping_timeout=10
                ) as ws:
                    await ws.send(json.dumps({
                        "jsonrpc": "2.0",
                        "id": 1,
                        "method": "logsSubscribe",
                        "params": [
                            {"mentions": [self.config['programs']['raydium']]},
                            {"commitment": "processed"}
                        ]
                    }))
                    
                    while self.active:
                        msg = await ws.recv()
                        data = json.loads(msg)
                        
                        if 'params' in data:
                            logs = data['params'].get('result', {}).get('value', {}).get('logs', [])
                            
                            for log in logs:
                                if "ray_log:" in log:
                                    raw_data = base64.b64decode(log.split('ray_log: ')[1].strip())
                                    await self.process_opportunity(raw_data)

            except Exception as e:
                logger.error(f"Mempool monitoring error: {e}", exc_info=True)
                await asyncio.sleep(1)

    async def process_opportunity(self, log_data: bytes) -> Optional[Dict]:
        logger.debug("Processing trading opportunity.")
        try:
            # Validate MEV protection
            if not self.mempool_analyzer.analyze_transaction(log_data):
                logger.warning("Opportunity validation failed.")
                return None

            # Analyze with GPU acceleration
            opportunity = await self.gpu_accelerator.analyze_opportunity(log_data)
            if not opportunity:
                logger.warning("Opportunity analysis returned no data.")
                return None

            logger.info(f"Opportunity found: {opportunity}")

            # Execute trade if profitable
            if opportunity['profit'] >= self.config['trading']['limits']['min_profit_pct']:
                params = TradeParams(
                    pool_address=self.config['accounts']['sol_wsol']['amm_id'],
                    amount_in=opportunity['amount_in'],
                    min_amount_out=opportunity['amount_out'] * (1 - self.config['execution']['slippage'])
                )

                signature = self.trading_core.execute_trade(params)
                logger.info(f"Trade executed: {signature}")

            return None
        except Exception as e:
            logger.error(f"Opportunity processing error: {e}", exc_info=True)
            return None

    async def start(self):
        try:
            logger.info("Starting trading system...")
            if not await self.initialize():
                logger.error("Initialization failed, stopping trading system.")
                return

            tasks = [
                self.monitor_mempool(),
                self.balance_manager.rebalance_if_needed()
            ]
            await asyncio.gather(*tasks)
        except Exception as e:
            logger.error(f"Startup error: {e}", exc_info=True)
        finally:
            if self.active:
                await self.cleanup()

    async def cleanup(self):
        logger.info("Cleaning up trading system...")
        try:
            self.active = False
            if self.gpu_accelerator:
                self.gpu_accelerator.cleanup()
            logger.info("Cleanup completed successfully.")
        except Exception as e:
            logger.error(f"Cleanup error: {e}", exc_info=True)

async def main():
    try:
        trader = RaydiumTrader('config.json')
        await trader.start()
    except Exception as e:
        logger.error(f"Fatal error in trading system: {e}", exc_info=True)

if __name__ == "__main__":
    torch.cuda.set_device(0)  # Set the GPU device (if applicable)
    torch.backends.cuda.matmul.allow_tf32 = True

    logger.info("PyTorch Version: {}".format(torch.__version__))
    logger.info("CUDA Version: {}".format(torch.version.cuda))
    logger.info("GPU Device: {}".format(torch.cuda.get_device_name()))

    asyncio.run(main()) can u do it and debug it please