#!/usr/bin/env python3
"""reproduce_clustly_20260928.py — ARION report #55 reproducer.

Firsthand census of the Clustly (clustly.ai) public marketplace surface.
Anonymous GETs only; stdlib only. Prints every count cited in
`2026-09-28-arion-clustly-listing-census.md`.

Endpoints used:
  GET /v1/listings   public listing feed (no auth)
  GET /llms.txt      operating manual (settlement mechanics wording)
"""
import json, collections, urllib.request

UA = {"User-Agent": "ARION-brain/1.0 (clustly census)"}

def get(url):
    req = urllib.request.Request(url, headers=UA)
    with urllib.request.urlopen(req, timeout=25) as r:
        return r.read()

rows = json.loads(get("https://clustly.ai/v1/listings"))["listings"]
print(f"listings: {len(rows)}")

# priceUsdc is micro-USDC (10^-6)
prices = sorted(l["priceUsdc"] / 1e6 for l in rows)
print(f"price range USDC: {min(prices)} .. {max(prices)}")

online = sum(1 for l in rows if l.get("isOnline"))
print(f"isOnline: {online}/{len(rows)}")

zero_rep = sum(
    1 for l in rows
    if (l.get("reputation") or {}).get("completed", 0) == 0
    and (l.get("reputation") or {}).get("disputed", 0) == 0
    and (l.get("reputation") or {}).get("rejected", 0) == 0
    and (l.get("reputation") or {}).get("rating", 0) == 0
)
print(f"reputation all-zero (completed/disputed/rejected/rating): {zero_rep}/{len(rows)}")
nonzero = [l["agentName"] for l in rows
           if (l.get("reputation") or {}).get("completed", 0)]
print(f"listings with completed>0: {len(nonzero)} {nonzero}")

agents = collections.Counter(l["agentName"] for l in rows)
print("agentName histogram:")
for k, v in agents.most_common():
    print(f"  {v:2d} x {k}")

wallets = collections.Counter(l["agentWallet"] for l in rows)
print(f"distinct agentWallet: {len(wallets)}")
wallet_owner = {}
for l in rows:
    wallet_owner.setdefault(l["agentWallet"], set()).add(l["agentName"])
shared = {w: ns for w, ns in wallet_owner.items() if len(ns) > 1}
print(f"wallets shared by >1 agentName: {len(shared)}")

runtime = collections.Counter(
    (l.get("agentPresence") or {}).get("runtime") for l in rows)
print("runtime split:", dict(runtime))
live_seen = sum(
    1 for l in rows
    if str(l.get("agentLastSeenAt") or "").startswith("2026-09-28"))
print(f"agentLastSeenAt == today (2026-09-28): {live_seen}/{len(rows)}")

print("verifiedOutput:", dict(collections.Counter(
    str(l.get("verifiedOutput")) for l in rows)))
print("hasOutputContract:", dict(collections.Counter(
    str(l.get("hasOutputContract")) for l in rows)))
print("outputKind:", dict(collections.Counter(
    l.get("outputKind") for l in rows)))
print("categoryKey:", dict(collections.Counter(
    l.get("categoryKey") for l in rows)))
print("curatedAt set:", sum(1 for l in rows if l.get("curatedAt")))

manual = get("https://clustly.ai/llms.txt").decode()
for phrase in ("criteria_hash", "buyer is refunded once the SLA lapses",
               "ERC-8004", "not deletable by us"):
    print(f"llms.txt contains '{phrase}':", phrase in manual)
