#!/usr/bin/env bash

set -euo pipefail

BASE_URL="${1:-https://explorer.d-bis.org}"

python3 - "$BASE_URL" <<'PY'
import re
import sys

import requests


base = sys.argv[1].rstrip("/")
session = requests.Session()
session.headers.update({"User-Agent": "ExplorerHealthCheck/2.0"})

failed = False

html_checks = [
    "/",
    "/home",
    "/blocks",
    "/transactions",
    "/addresses",
    "/bridge",
    "/routes",
    "/weth",
    "/tokens",
    "/pools",
    "/watchlist",
    "/more",
    "/analytics",
    "/operator",
    "/system",
    "/liquidity",
    "/wallet",
    "/snap/",
    "/docs.html",
    "/privacy.html",
    "/terms.html",
    "/acknowledgments.html",
]

json_checks = [
    "/api/v2/stats",
    "/api/config/token-list",
    "/api/config/networks",
    "/api/config/capabilities",
    "/config/CHAIN138_RPC_CAPABILITIES.json",
    "/config/topology-graph.json",
    "/config/mission-control-verify.example.json",
    "/explorer-api/v1/features",
    "/explorer-api/v1/ai/context?q=cUSDT",
    "/explorer-api/v1/track1/bridge/status",
    "/explorer-api/v1/mission-control/liquidity/token/0x93E66202A11B1772E55407B32B44e5Cd8eda7f22/pools",
    "/token-aggregation/api/v1/routes/tree?chainId=138&tokenIn=0x93E66202A11B1772E55407B32B44e5Cd8eda7f22&tokenOut=0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1&amountIn=1000000",
    "/token-aggregation/api/v1/routes/matrix",
    "/token-aggregation/api/v1/routes/ingestion?fromChainId=138&routeType=swap",
    "/token-aggregation/api/v1/routes/partner-payloads?partner=0x&amount=1000000&includeUnsupported=true",
]

asset_checks = [
    "/token-icons/cUSDC.png",
    "/token-icons/cUSDT.png",
    "/token-icons/cXAUC.png",
    "/token-icons/cXAUT.png",
]


def mark_failure(message):
    global failed
    failed = True
    print(message)


print("== Public routes ==")
for path in html_checks:
    url = base + path
    try:
        resp = session.get(url, timeout=20, allow_redirects=True)
        ctype = resp.headers.get("content-type", "")
        print(f"{resp.status_code:>3}  {path}  [{ctype[:60]}]")
        if resp.status_code >= 400:
            failed = True
    except Exception as exc:
        mark_failure(f"ERR  {path}  [{exc}]")

print("\n== JSON and API surfaces ==")
for path in json_checks:
    url = base + path
    try:
        resp = session.get(url, timeout=20, allow_redirects=True)
        ctype = resp.headers.get("content-type", "")
        print(f"{resp.status_code:>3}  {path}  [{ctype[:60]}]")
        if resp.status_code >= 400:
            failed = True
            continue
        if "json" not in ctype:
            failed = True
            print(f"     expected JSON content-type, got: {ctype}")
            continue
        payload = resp.json()
        if path == "/api/config/capabilities":
            if payload.get("chainId") != 138:
                mark_failure("     capabilities JSON does not report chainId 138")
            wallet_support = payload.get("walletSupport", {})
            if wallet_support.get("walletWatchAsset") is not True:
                mark_failure("     capabilities JSON does not advertise walletWatchAsset")
        elif path == "/api/config/token-list":
            tokens = payload.get("tokens", [])
            if not tokens:
                mark_failure("     token list is empty")
        elif path == "/api/config/networks":
            chains = payload.get("chains", [])
            if not chains:
                mark_failure("     networks payload does not include any chains")
        elif path == "/explorer-api/v1/features":
            if "features" not in payload:
                mark_failure("     features payload is missing the features key")
        elif path == "/explorer-api/v1/track1/bridge/status":
            data = payload.get("data", {})
            relays = data.get("ccip_relays", {})
            expected_relays = {
                "avax",
                "avax_cw",
                "avax_to_138",
                "bsc",
                "mainnet_cw",
                "mainnet_weth",
            }
            missing = sorted(expected_relays - set(relays))
            if missing:
                mark_failure(f"     bridge status is missing relay keys: {', '.join(missing)}")
            if data.get("status") not in {"operational", "paused", "degraded"}:
                mark_failure("     bridge status payload does not include a recognized overall status")
    except Exception as exc:
        mark_failure(f"ERR  {path}  [{exc}]")

print("\n== Static assets ==")
for path in asset_checks:
    url = base + path
    try:
        resp = session.get(url, timeout=20, allow_redirects=True)
        ctype = resp.headers.get("content-type", "")
        print(f"{resp.status_code:>3}  {path}  [{ctype[:60]}]")
        if resp.status_code >= 400:
            failed = True
    except Exception as exc:
        mark_failure(f"ERR  {path}  [{exc}]")

print("\n== Mission-control SSE ==")
stream_url = base + "/explorer-api/v1/mission-control/stream"
try:
    with session.get(stream_url, timeout=(20, 20), stream=True) as resp:
        ctype = resp.headers.get("content-type", "")
        print(f"{resp.status_code:>3}  /explorer-api/v1/mission-control/stream  [{ctype[:60]}]")
        if resp.status_code >= 400:
            failed = True
        else:
            lines = []
            for raw in resp.iter_lines(decode_unicode=True):
                if raw:
                    lines.append(raw)
                if len(lines) >= 2:
                    break
            if not any(line.startswith("event:") for line in lines):
                mark_failure("     mission-control stream did not emit an event line")
            if not any(line.startswith("data:") for line in lines):
                mark_failure("     mission-control stream did not emit a data line")
except Exception as exc:
    mark_failure(f"ERR  /explorer-api/v1/mission-control/stream  [{exc}]")

print("\n== Internal href targets from homepage ==")
try:
    home = session.get(base + "/", timeout=20).text
    hrefs = sorted(set(re.findall(r'href=\"([^\"]+)\"', home)))
    for href in hrefs:
        if href.startswith("/") and not href.startswith("//"):
            resp = session.get(base + href, timeout=20, allow_redirects=True)
            print(f"{resp.status_code:>3}  {href}")
            if resp.status_code >= 400:
                failed = True
except Exception as exc:
    mark_failure(f"ERR  homepage href sweep failed: {exc}")

print("\n== External explorer roots referenced by bridge surfaces ==")
external_roots = [
    "https://etherscan.io/",
    "https://bscscan.com/",
    "https://polygonscan.com/",
    "https://subnets.avax.network/c-chain",
    "https://basescan.org/",
    "https://arbiscan.io/",
    "https://optimistic.etherscan.io/",
]
for url in external_roots:
    try:
        resp = session.get(url, timeout=20, allow_redirects=True)
        print(f"{resp.status_code:>3}  {url}")
    except Exception as exc:
        print(f"ERR  {url}  [{exc}]")

if failed:
    sys.exit(1)
PY
