# Issue #96: REST → WebSocket junction validation
# Proves that trades flow continuously from REST API to WebSocket stream
# with monotonically increasing agg_trade_ids.

import asyncio
import json

import requests
import websockets

SYMBOL = "BTCUSDT"
REST_URL = "https://api.binance.com/api/v3/aggTrades"
WS_URL = f"wss://stream.binance.com:9443/ws/{SYMBOL.lower()}@aggTrade"


async def test_rest_to_ws_junction():
    """Fetch latest REST trades, then connect WS and check ID continuity."""
    print("=== REST → WebSocket Junction Test ===\n")

    # Step 1: Get latest trades from REST
    print("1. Fetching latest REST trades...")
    resp = requests.get(REST_URL, params={"symbol": SYMBOL, "limit": "10"}, timeout=10)
    rest_trades = resp.json()
    rest_last = rest_trades[-1]
    rest_last_id = rest_last["a"]
    rest_last_ts = rest_last["T"]
    print(f"   REST last: id={rest_last_id}, T={rest_last_ts}")

    # Step 2: Connect WebSocket and collect first 20 trades
    print("2. Connecting WebSocket...")
    ws_trades = []

    async with websockets.connect(WS_URL) as ws:
        print("   Connected. Collecting first 20 trades...")
        for i in range(20):
            raw = await asyncio.wait_for(ws.recv(), timeout=10)
            trade = json.loads(raw)
            ws_trades.append(trade)
            if i < 5 or i == 19:
                print(f"   WS[{i:2d}]: id={trade['a']}, T={trade['T']}, p={trade['p']}")

    ws_first = ws_trades[0]
    ws_first_id = ws_first["a"]

    # Step 3: Analyze junction
    print("\n3. Junction Analysis:")
    print(f"   REST last id:  {rest_last_id}")
    print(f"   WS first id:   {ws_first_id}")
    id_delta = ws_first_id - rest_last_id
    print(f"   ID delta:       {id_delta}")
    print(f"   Time delta:     {(ws_first['T'] - rest_last_ts)/1000:.1f} sec")

    if id_delta > 0:
        print(f"   Status: MONOTONIC (gap of {id_delta-1} trades during connection setup)")
    elif id_delta == 0:
        print("   Status: OVERLAP by 1 (same trade in both sources)")
    else:
        print(f"   Status: OVERLAP by {abs(id_delta)+1} (WS started before REST ended)")

    # Step 4: Can we bridge the gap with fromId?
    if id_delta > 1:
        print(f"\n4. Bridging gap with fromId={rest_last_id+1}...")
        resp = requests.get(REST_URL, params={
            "symbol": SYMBOL,
            "fromId": str(rest_last_id + 1),
            "limit": "1000",
        }, timeout=10)
        bridge = resp.json()
        if bridge:
            bridge_last_id = bridge[-1]["a"]
            print(f"   Bridge: {len(bridge)} trades, id {bridge[0]['a']}..{bridge_last_id}")
            # Check if bridge reaches WS
            if bridge_last_id >= ws_first_id:
                print(f"   Bridge reaches WS start: YES (overlap by {bridge_last_id - ws_first_id + 1})")
                print("   Dedup strategy: filter bridge where id < ws_first_id")
            else:
                remaining_gap = ws_first_id - bridge_last_id - 1
                print(f"   Bridge reaches WS start: NO ({remaining_gap} trades still missing)")
                print("   Need more REST pages to close gap")

    # Step 5: WS internal contiguity
    print("\n5. WebSocket internal contiguity:")
    ws_gaps = 0
    for i in range(1, len(ws_trades)):
        if ws_trades[i]["a"] != ws_trades[i-1]["a"] + 1:
            ws_gaps += 1
            print(f"   Gap: id {ws_trades[i-1]['a']} → {ws_trades[i]['a']}")
    print(f"   Gaps: {ws_gaps} (in {len(ws_trades)} trades)")


asyncio.run(test_rest_to_ws_junction())
