import asyncio
import json
import base64
import time
import logging
from typing import List, Optional, Dict
from optimized_parser import OptimizedParser

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

async def test_parser():
   with open('config.json', 'r') as f:
       config = json.load(f)
   
   parser = OptimizedParser(config)
   
   test_scenarios = [
       {
           "type": "direct",
           "input": {
               "amount_in": 0.5,
               "amount_out": 0.51,
               "pool": "2e1f6xmy" # Shortened for hex validity
           }
       },
       {
           "type": "triangle",
           "input": {
               "amounts": [0.5, 0.51, 0.515],
               "pool": "2e1f6xmy"
           }
       },
       {
           "type": "multi_hop",
           "input": {
               "amounts": [0.5, 0.508, 0.5125],
               "pool": "2e1f6xmy"
           }
       },
       {
           "type": "sandwich",
           "input": {
               "front_run": 0.1,
               "victim": 5.0,
               "back_run": 0.1015,
               "pool": "2e1f6xmy"
           }
       }
   ]

   print("\n🚀 Testing Trading Methods\n")
   
   for scenario in test_scenarios:
       print(f"\n📊 {scenario['type'].upper()}")
       print("-" * 40)
       
       log = create_test_log(scenario)
       opportunity = await parser.parse_log(log)
       
       if opportunity:
           print_details(opportunity)
           await validate_and_check(parser, opportunity)
       else:
           print("❌ Rejected")

def create_test_log(scenario: Dict) -> str:
   LAMPORTS_PER_SOL = 1_000_000_000
   raw_data = bytearray()
   
   if scenario['type'] == 'direct':
       amount_in = int(scenario['input']['amount_in'] * LAMPORTS_PER_SOL)
       amount_out = int(scenario['input']['amount_out'] * LAMPORTS_PER_SOL)
       raw_data.extend(amount_in.to_bytes(8, 'little'))
       raw_data.extend(amount_out.to_bytes(8, 'little'))
       raw_data.extend(bytes(48))
   elif scenario['type'] == 'sandwich':
       for amount in [scenario['input']['front_run'], 
                     scenario['input']['victim'], 
                     scenario['input']['back_run']]:
           raw_data.extend(int(amount * LAMPORTS_PER_SOL).to_bytes(8, 'little'))
       raw_data.extend(bytes(32))
   else:  # triangle or multi-hop
       for amount in scenario['input']['amounts']:
           raw_data.extend(int(amount * LAMPORTS_PER_SOL).to_bytes(8, 'little'))
       raw_data.extend(bytes(32))
   
   # Add pool address with proper padding
   pool_hex = scenario['input']['pool'].ljust(64, '0')
   raw_data.extend(bytes.fromhex(pool_hex))
   
   return format_ray_log(raw_data)

def format_ray_log(raw_data: bytes) -> str:
   b64_data = base64.b64encode(raw_data).decode()
   return json.dumps({
       "params": {
           "result": {
               "value": {
                   "logs": [f"ray_log: {b64_data}"]
               }
           }
       }
   })

def print_details(opp):
   print(f"Amount In: {opp.amount_in:.6f} SOL")
   print(f"Amount Out: {opp.amount_out:.6f} SOL")
   print(f"Profit %: {opp.profit_pct:.2f}%")
   print(f"Impact: {opp.impact:.4f}")

async def validate_and_check(parser, opp):
   is_valid = await parser.validate_opportunity(opp)
   print(f"\nValid: {'✅' if is_valid else '❌'}")
   
   if is_valid:
       safety = await parser.analyze_safety(opp)
       print("\nSafety:")
       for check, failed in vars(safety).items():
           print(f"{check}: {'❌' if failed else '✅'}")
       
       if not any(vars(safety).values()):
           print(f"\nNet Profit: {parser._calculate_net_profit(opp):.6f} SOL")

if __name__ == "__main__":
   asyncio.run(test_parser()) add debug logging so i can know whats wrong please everywhere