"""twikit yaması — X'in değişen JS paket formatı.

SORUN
-----
twikit 2.3.3, her isteğe eklenen `x-client-transaction-id` başlığını üretmek için
X'in `ondemand.s.<hash>a.js` dosyasını indirip içinden KEY_BYTE indekslerini
çıkarır. Dosyanın hash'ini ana sayfada şu desenle arar:

    "ondemand.s":"<hash>"

X paketleme biçimini değiştirdi; artık hash tek parça değil, iki ayrı haritada:

    59924:"ondemand.s"     <- chunk id -> isim haritası
    59924:"25d3ef4"        <- chunk id -> hash haritası

Eski desen hiçbir şey bulamayınca twikit `Couldn't get KEY_BYTE indices`
hatası fırlatıyor ve HİÇBİR istek çalışmıyor (giriş dahil).

ÇÖZÜM
-----
`ClientTransaction.get_indices` metodunu sarmalıyoruz: önce eski deseni dener
(X geri dönerse veya başka bir sürümde çalışıyorsa bozulmasın), bulamazsa yeni
chunk-harita yöntemini uygular. Kütüphane dosyalarına dokunulmaz; twikit
güncellense de yama zararsızca durur.

Doğrulama (17.08.2026): chunk id 59924, hash 25d3ef4 ->
ondemand.s.25d3ef4a.js (HTTP 200) -> indeksler [5, 19, 28, 38]
"""
import logging
import re

from twikit.x_client_transaction import transaction as _tx

log = logging.getLogger("x_engine.patch")

# Yeni format: chunk id -> isim, ve chunk id -> hash (iki ayrı harita)
_CHUNK_ID_RE = re.compile(r'(\d+):"ondemand\.s"')
_BASE_URL = "https://abs.twimg.com/responsive-web/client-web"

_applied = False


def _find_ondemand_hash(page_source: str) -> str | None:
    """Yeni chunk-harita biçiminden ondemand.s hash'ini çıkar."""
    m = _CHUNK_ID_RE.search(page_source)
    if not m:
        return None
    chunk_id = m.group(1)
    # aynı sayfada: <chunk_id>:"<hash>"  (isim haritasındaki eşleşme hariç)
    for hm in re.finditer(rf'{chunk_id}:"([a-f0-9]{{5,}})"', page_source):
        return hm.group(1)
    return None


async def _patched_get_indices(self, home_page_response, session, headers):
    key_byte_indices = []
    response = self.validate_response(home_page_response) or self.home_page_response
    page_source = str(response)

    # 1) Eski yol: "ondemand.s":"<hash>"
    on_demand_file = _tx.ON_DEMAND_FILE_REGEX.search(page_source)
    file_hash = on_demand_file.group(1) if on_demand_file else None

    # 2) Yeni yol: chunk haritası
    if not file_hash:
        file_hash = _find_ondemand_hash(page_source)
        if file_hash:
            log.debug("ondemand.s hash'i chunk haritasından alındı: %s", file_hash)

    if not file_hash:
        raise Exception(
            "ondemand.s dosyası bulunamadı — X sayfa yapısı yine değişmiş olabilir. "
            "app/x_engine/twikit_patch.py güncellenmeli."
        )

    url = f"{_BASE_URL}/ondemand.s.{file_hash}a.js"
    resp = await session.request(method="GET", url=url, headers=headers)
    for item in _tx.INDICES_REGEX.finditer(str(resp.text)):
        key_byte_indices.append(item.group(2))

    if not key_byte_indices:
        raise Exception(
            f"KEY_BYTE indeksleri çıkarılamadı ({url}) — desen eskimiş olabilir."
        )

    key_byte_indices = list(map(int, key_byte_indices))
    return key_byte_indices[0], key_byte_indices[1:]


def apply():
    """Yamayı bir kez uygula. twikit kullanılmadan önce çağrılmalı."""
    global _applied
    if _applied:
        return
    _tx.ClientTransaction.get_indices = _patched_get_indices
    _applied = True
    log.info("twikit yaması uygulandı (ondemand.s chunk haritası)")
