import asyncio
import json
import sys

# rnet senin ortamındaki gibi:
from rnet import Client, Emulation

PEET_URL = "https://tls.peet.ws/api/all"

# burada candidate'leri istediğin gibi çoğaltabilirsin
TLS_CANDIDATES = [
    ("random_extension", True),
    ("random_extension", False),

    # ALPN oynaması
    ("alpn", ["h2", "http/1.1"]),
    ("alpn", ["h2"]),
    ("alpn", ["http/1.1"]),

    # SNI zorlaması
    ("sni", "tls.peet.ws"),
    ("sni", "example.com"),

    # ticket (bazı stack'lerde name 'session_ticket' ya da 'enable_session_ticket' olabilir)
    ("session_ticket", True),
    ("session_ticket", False),

    # TLS GREASE toggle
    ("grease", True),
    ("grease", False),

    # client hello padding (bazı client'lar int bekler)
    ("client_hello_padding", True),
    ("client_hello_padding", 1),

    # ECH / Encrypted Client Hello (çoğu zaman backend zaten ekliyor)
    ("ech", True),
    ("encrypted_client_hello", True),

    # signature algs
    ("signature_algorithms", [
        "ecdsa_secp256r1_sha256",
        "rsa_pss_rsae_sha256",
        "rsa_pkcs1_sha256",
    ]),

    # curve / groups
    ("supported_groups", ["X25519MLKEM768", "X25519", "P-256", "P-384"]),
    ("groups", ["X25519", "P-256", "P-384"]),

    # key share explicit
    ("key_share", {"groups": ["X25519"]}),

    # JA3 override ihtimali
    ("ja3", "771,4865-4866-4867,0-10-11,29-23,0"),
]

async def probe_one(name, value, http2_only=True):
    """
    Tek bir TLS parametresiyle client kurup isteği at.
    DÖNDÜRDÜĞÜ şey: dict
    """
    tls_obj = {name: value}
    try:
        client = Client(
            emulation=Emulation.Chrome141,
            cookie_store=True,
            allow_redirects=True,
            http2_only=http2_only,
            tls=tls_obj,
        )
    except Exception as e:
        return {
            "where": "client",
            "param": name,
            "value": repr(value),
            "http2_only": http2_only,
            "result": "CLIENT_INIT_ERROR",
            "error": repr(e),
            "http_version": "",
            "tls_negotiated": "",
            "ja3": "",
            "ja3_hash": "",
            "alpn_listed": "",
        }

    try:
        # rnet genelde method string de kabul ediyor ama senin binding'in Method enum isteyebilir;
        # stringle dener, olmazsa GET enum'una düşeriz
        resp = await client.request(
            "GET",
            PEET_URL,
            default_headers=False,
            headers={"accept": "*/*"},
        )
    except TypeError:
        # enum fallback
        from rnet import Method
        resp = await client.request(
            Method.GET,
            PEET_URL,
            default_headers=False,
            headers={"accept": "*/*"},
        )
    except Exception as e:
        return {
            "where": "request",
            "param": name,
            "value": repr(value),
            "http2_only": http2_only,
            "result": "REQUEST_ERROR",
            "error": repr(e),
            "http_version": "",
            "tls_negotiated": "",
            "ja3": "",
            "ja3_hash": "",
            "alpn_listed": "",
        }

    try:
        data = await resp.json()
    except Exception:
        text = await resp.text()
        data = {"raw": text}

    tls = data.get("tls", {})
    http2 = data.get("http2", {})
    return {
        "where": "client",
        "param": name,
        "value": repr(value),
        "http2_only": http2_only,
        "result": "OK",
        "error": "",
        "http_version": data.get("http_version", ""),
        "tls_negotiated": tls.get("tls_version_negotiated", ""),
        "ja3": tls.get("ja3", ""),
        "ja3_hash": tls.get("ja3_hash", ""),
        "alpn_listed": ",".join(http2.get("sent_frames", [{}])[0].get("settings", [])) if http2 else "",
    }

async def main():
    rows = []
    # Windows için loop policy
    if sys.platform.startswith("win"):
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())  # type: ignore[attr-defined]

    for name, value in TLS_CANDIDATES:
        # hem http2_only True hem False dene
        for h2_only in (True, False):
            res = await probe_one(name, value, h2_only)
            rows.append(res)

    # CSV gibi yaz
    headers = [
        "where","param","value","http2_only","result","error",
        "http_version","tls_negotiated","ja3","ja3_hash","alpn_listed"
    ]
    print(",".join(headers))
    for r in rows:
        print(",".join(str(r.get(h, "")) for h in headers))

if __name__ == "__main__":
    asyncio.run(main())
