"""On-chain oracle reader — reads WZRD signals from Switchboard, not the server.

This module provides a trustless alternative to the HTTP API. Instead of calling
api.twzrd.xyz, it reads Switchboard On-Demand feeds via the Crossbar simulation
endpoint. The simulation runs in TEEs (Trusted Execution Environments) — the
oracle value is computed by Switchboard oracles, not our server.

Usage:
    from wzrd.oracle import pick_onchain, read_velocity, read_price

    # Pick model using on-chain oracle (no server dependency)
    model = await pick_onchain("code")

    # Read raw velocity for a specific feed
    velocity = await read_velocity("qwen-3.5-9b")

    # Read CCM/USD price from on-chain
    price = await read_price("ccm")

Falls back to HTTP API if Crossbar is unavailable.
"""

from __future__ import annotations

import json
import logging
from typing import Any, Optional
from urllib.error import URLError
from urllib.request import Request, urlopen

logger = logging.getLogger("wzrd.oracle")

CROSSBAR_URL = "https://crossbar.switchboard.xyz"
QUEUE = "A43DyUGA7s8eXPxqEjJY6EBu1KKbNgfxF8h17VAHn13w"

# Feed registry — maps human names to Switchboard feed hashes
VELOCITY_FEEDS = {
    "qwen-3.5-9b": {"hash": "5db4a3ff6719e48d1f7aafc6b472efe721ac541dff60db5cbb0604890d79f4a1", "market_id": 14, "name": "Qwen 3.5 9B"},
    "qwen-3.5-35b": {"hash": "26b2b7735589b977c9eff764171c27c8396af0a3892800f7e0c4c9b1f3ee739c", "market_id": 16, "name": "Qwen 3.5 35B-A3B"},
    "qwen-2.5-72b": {"hash": "6b7c0e102d574345eab4985a75fe3704103be854405ab56e06af88c5493e37e5", "market_id": 10, "name": "Qwen 2.5 72B"},
    "llama-3.3-70b": {"hash": "04912993aaa414debf49afb48201f3b54152aa6aa7174b7ad0c80238944f3594", "market_id": 3, "name": "Llama 3.3 70B"},
    "kimi-k2.5": {"hash": "6b435ba087d48b0e13d4ea5ab7ff78b7d9f9b6fb0a79b0b7686c8be2079bb830", "market_id": 79, "name": "Kimi K2.5"},
    "glm-ocr": {"hash": "47c51bcd675d3703282ee4d8962b270aaf175afaca26dc5a676d6b49cafa0e51", "market_id": 90, "name": "GLM-OCR"},
    "qwen-3.5-35b-gguf": {"hash": "876e7f5487ceadd2763740112eb52f28a400781838fb0bc4905b96a10f4cd5e9", "market_id": 22, "name": "Qwen 3.5 35B GGUF"},
    "qwen-3.5-27b": {"hash": "ae9281781b42168da39961c7f48600b40a1761a58111aedeadb479c01720a091", "market_id": 70, "name": "Qwen 3.5 27B"},
    "qwen-3.5-397b": {"hash": "af0dca08ca3c7fed18e8675a7efbe174168b9f924416cd7ab54722f3adc4e8bf", "market_id": 73, "name": "Qwen 3.5 397B MoE"},
    "glm-4.7-flash": {"hash": "b53ddbf0bf78af8ab102324538e493977e29ddb4d99cff70d89e7e253ac718c3", "market_id": 82, "name": "GLM-4.7 Flash"},
    "qwen-3.5-4b": {"hash": "9f74eb6f388052c7ed4a7ad96ddc292bce978eb08cd55df30ed5f7c255d044f6", "market_id": 18, "name": "Qwen 3.5 4B"},
    "qwen-3.5-0.8b": {"hash": "12b836cfda5563611246e64fa94a79d5e475ee55b3a71dec67c3b3504681009a", "market_id": 17, "name": "Qwen 3.5 0.8B"},
    "qwen3-coder-next": {"hash": "86bc2b82f735e103aaf2004963ed14f7af3e13c860033710a21b3eb05fa796c6", "market_id": 76, "name": "Qwen3-Coder-Next"},
    "mimo-v2-omni": {"hash": "720e476068264605d61a3863ee2e31baa59780c88fb27f2d08f1a10c5b826d9e", "market_id": 92, "name": "MiMo V2 Omni"},
    "ltx-2.3": {"hash": "a89277acc660c218a6a54cb76574be963170d61c722568fe4680c730364cf4b3", "market_id": 15, "name": "LTX-2.3"},
}

PRICE_FEEDS = {
    "ccm": {"hash": "4db6dec03005f946d72c0347d5b638b5316ef0106f9b3cae1a9773edd32c924e", "name": "CCM/USD"},
    "vlofi": {"hash": "6d860548887c338dfbe1c4f89564e84855531a23fa55e38fec42df4965d57e57", "name": "vLOFI/USD"},
}


def _simulate_feed(feed_hash: str, timeout: float = 10.0) -> Optional[float]:
    """Simulate a single Switchboard feed via Crossbar.

    Returns the oracle-computed value, or None on failure.
    The simulation runs in a TEE — the value is trustless.
    Crossbar oracles fetch data from the source URL, compute the result,
    and return it signed. This is the same pipeline as on-chain updates.
    """
    # Crossbar simulateFeed endpoint: GET /simulate/{feedHash}
    url = f"{CROSSBAR_URL}/simulate/{feed_hash}"
    try:
        req = Request(url, headers={"Accept": "application/json"})
        data = json.loads(urlopen(req, timeout=timeout).read())

        # Response format: [{"feedHash": "...", "results": ["3278420.0"], ...}]
        # or: {"feedId": "...", "results": ["3278420.0"], ...}
        if isinstance(data, list) and len(data) > 0:
            data = data[0]
        if isinstance(data, dict):
            results = data.get("results", [])
            if results and len(results) > 0:
                return float(results[0])

        return None
    except Exception as exc:
        logger.debug("oracle: simulate %s failed: %s", feed_hash[:16], exc)
        return None


def read_velocity(model_key: str) -> Optional[float]:
    """Read velocity EMA for a model from Switchboard oracle.

    Args:
        model_key: lowercase slug like "qwen-3.5-9b" or "llama-3.3-70b"

    Returns:
        Velocity EMA value from the on-chain oracle, or None if unavailable.
    """
    feed = VELOCITY_FEEDS.get(model_key)
    if not feed:
        logger.warning("oracle: unknown model key '%s'", model_key)
        return None
    return _simulate_feed(feed["hash"])


def read_price(token: str) -> Optional[float]:
    """Read token price from Switchboard oracle.

    Args:
        token: "ccm" or "vlofi"

    Returns:
        USD price from oracle, or None if unavailable.
    """
    feed = PRICE_FEEDS.get(token.lower())
    if not feed:
        return None
    return _simulate_feed(feed["hash"])


def read_all_velocities() -> dict[str, float]:
    """Read all velocity feeds from Switchboard.

    Returns dict of {model_key: velocity_ema}.
    Skips feeds that fail to simulate.
    """
    results = {}
    for key, feed in VELOCITY_FEEDS.items():
        val = _simulate_feed(feed["hash"])
        if val is not None:
            results[key] = val
    return results


def pick_onchain(task: str = "general") -> Optional[str]:
    """Pick the best model using Switchboard oracle data — no server dependency.

    This is the trustless equivalent of wzrd.pick(). Instead of calling
    api.twzrd.xyz, it reads Switchboard feeds via Crossbar simulation.

    Falls back to the HTTP API if oracle reads fail.
    """
    velocities = read_all_velocities()
    if not velocities:
        logger.info("oracle: no feeds available, falling back to HTTP API")
        from .client import pick
        return pick(task)

    # Simple: return the model with highest velocity
    best_key = max(velocities, key=velocities.get)  # type: ignore
    feed = VELOCITY_FEEDS[best_key]
    return feed["name"]


# Export the feed registry for programmatic access
def list_feeds() -> dict[str, dict]:
    """List all available Switchboard feed hashes."""
    return {
        "velocity": {k: {"hash": v["hash"], "name": v["name"]} for k, v in VELOCITY_FEEDS.items()},
        "price": {k: {"hash": v["hash"], "name": v["name"]} for k, v in PRICE_FEEDS.items()},
    }
