"""Direct tube scrapers.

Każdy scraper hit'uje tube bezpośrednio HTTPm — różne tube'y to różne rate limit
budgets, więc mogą iść równolegle. Wszystkie feedują sceny do tej samej
`Source(name=SCRAPER_SOURCE_NAME)` z external_id `f"{sitetag}:{url}"`. Resolver
mergeuje idempotentnie po tym kluczu.

Nazwa źródła: do 2026-06-07 brzmiała `"pornapp"` — myląca pozostałość po usuniętym
zewnętrznym porn-app API (sugerowała zależność od obcego serwisu, której NIE MA —
to nasze własne direct-scrapery tubów). Przemianowana na `"tube-scraper"`; wiersz
`sources` zaktualizowany w DB (UPDATE name) więc cała historia ingest_runs została.

Search-based ścieżka (per performer name); category browse'ng przez `categoriesUrl`.

UWAGA — speculative scrapers: większość aggregator + special tubes (xmoviesforyou,
watchporn, siska, porn4days, porndish, xxxfreewatch, latestleaks, mypornerleak,
porndittcom, perverzija, fpoxxx, ...) ma URL templates + regex'y oparte na typowych
WordPress conventions. Wymagają post-deploy verification — gdy któryś nie zwraca
wyników, sprawdź real search HTML + popraw template/regex w odpowiednim pliku.
"""
# Umbrella Source.name dla wszystkich direct-scraperów (deep-crawl, browse-latest,
# performer-driven). Rename z legacy "pornapp" 2026-06-07 (mylące — nie ma zależności
# od zewnętrznego porn-app API).
SCRAPER_SOURCE_NAME = "tube-scraper"

from app.connectors.direct_scrapers._browse_base import BaseBrowseScraper
from app.connectors.direct_scrapers.base import BaseDirectTubeScraper
from app.connectors.direct_scrapers.eporner import EpornerScraper
from app.connectors.direct_scrapers.fpoxxx import FpoxxxScraper
from app.connectors.direct_scrapers.hdporn92 import HDPorn92Scraper  # noqa: F401 — kept for backref; disabled
from app.connectors.direct_scrapers.hqporner import HQPornerScraper
from app.connectors.direct_scrapers.latestleaks import LatestLeaksScraper
from app.connectors.direct_scrapers.latestpornvideo import LatestPornVideoScraper
from app.connectors.direct_scrapers.mypornerleak import MyPornerLeakScraper
from app.connectors.direct_scrapers.mypornerleak_browse import MyPornerLeakBrowseScraper
from app.connectors.direct_scrapers.perverzija import PerverzijaScraper
from app.connectors.direct_scrapers.porn4days import Porn4DaysScraper
from app.connectors.direct_scrapers.porndish import PornDishScraper
from app.connectors.direct_scrapers.porntrex import PornTrexScraper
from app.connectors.direct_scrapers.porntrex_browse import PornTrexBrowseScraper
from app.connectors.direct_scrapers.xnxx_browse import XnxxBrowseScraper
from app.connectors.direct_scrapers.youporn_browse import YouPornBrowseScraper
from app.connectors.direct_scrapers.siska import SiskaScraper
from app.connectors.direct_scrapers.sxyland import SxyLandScraper
from app.connectors.direct_scrapers.sxyprn import SxyPrnScraper
from app.connectors.direct_scrapers.watchporn import WatchPornScraper
from app.connectors.direct_scrapers.xhamster import XHamsterScraper
from app.connectors.direct_scrapers.xmoviesforyou import XMoviesForYouScraper
from app.connectors.direct_scrapers.xnxx import XnxxScraper
from app.connectors.direct_scrapers.xvideos import XVideosScraper
from app.connectors.direct_scrapers.xxxfreewatch import XxxFreeWatchScraper  # noqa: F401 — kept for backref; delisted
from app.connectors.direct_scrapers.youporn import YouPornScraper

ALL_DIRECT_SCRAPERS: list[type[BaseDirectTubeScraper]] = [
    # Existing 4 (verified, in production)
    HQPornerScraper,
    # HDPorn92Scraper — wyłączony 2026-05-18. Scene pages to SEO shell: ZERO player iframe
    # (tylko happyleafmotion ads), JS hijackuje wszystkie kliki → `go.rmishe.com/smartpop/...`
    # popunder redirect. Mobile WebView page-as-hoster pokazuje ad redirect zamiast video.
    # 33,598 playback_sources mass-marked dead, 27,374 solo-orphan scenes deleted.
    SxyLandScraper,
    # ZeroDayXXScraper (0dayxx) — USUNIĘTY CAŁKOWICIE 2026-06-22 (user request). Orphan
    # factory (0.1% canonical), zastępujemy lepszymi źródłami. Dane/pliki/extractor skasowane.
    # Mainstream (URL templates well-known)
    # PornHub + RedTube — USUNIĘTE CAŁKOWICIE 2026-06-22 (user request). Disabled od
    # 2026-05-12 (0.4% canonical match), zamrożone dane skasowane z DB, pliki scraperów
    # i ekstraktory usunięte. Powód: skrócone amatorskie clipy, nigdy nie matchują studio.
    XVideosScraper,
    XnxxScraper,
    XHamsterScraper,
    YouPornScraper,
    PornTrexScraper,
    EpornerScraper,
    # Aggregators (WordPress-like ?s= search; speculative — verify post-deploy)
    # XMoviesForYouScraper — wyłączony 2026-05-12 (post audit fix). 100% scen serwuje
    # streamtape (DEAD_HOSTER_RE — malware drive-by .reg) + opcjonalnie playmogo/mixdrop.
    # Mixdrop zrebrandował na m1xdrop.bz, yt-dlp out-of-date, packer/JS extract = fail.
    # Playmogo = DoodStream CAPTCHA. Porn-app sam olewa xmoviesforyou (brak handlera w
    # jadx). 1,321 solo-orphan scen.
    # WatchPornScraper — wyłączony 2026-05-12 (user bug-report). Wszystkie iframes to
    # DoodStream variants (playmogo/d0000d/dooood/mivalyo) z CAPTCHA gate. WebView na
    # mobile = black screen (player JS nie inicjalizuje się przez Turnstile). 16%
    # scen solo (no backup tube), 84% multi-source — user może użyć innego tube. yt-dlp
    # nie wspiera DoodStream ("Piracy"), własny resolver TBD jeśli warto.
    # SiskaScraper — przeniesiony do ALL_BROWSE_SCRAPERS (browse-konwersja 2026-06-20,
    # bo search siski zepsuty site-side — `?s=` ignoruje query). Patrz siska.py.
    # Porn4DaysScraper — wyłączony 2026-05-12 (post audit fix). 100% scen na streamtape
    # only (DEAD_HOSTER_RE blacklist - malware drive-by .reg downloads). SERVER1_URL =
    # streamtape, brak SERVER2/SERVER3 backup. Porn-app sam olewa porn4days. 10,346
    # solo-orphan scen.
    # PornDishScraper — przeniesiony do ALL_BROWSE_SCRAPERS (browse-konwersja 2026-06-24,
    # watchdog GOON-16: search `?s=` zamarzł 2026-05-07). WordPress → browse przez WP REST
    # API (/wp-json/wp/v2/posts) jak perverzija: tytuł/data/thumb/studio(category)/tagi.
    # XxxFreeWatchScraper — wyłączony 2026-05-18. 790 scen, 0% canonical match, 100% solo-orphan.
    # Cloudflare 403 z VPS IP, mobile WebView teoretycznie działa ale 0/790 scen miało jakikolwiek
    # match do TPDB/StashDB. Pure orphan factory. Solo scenes deleted, scraper disabled.
    # LatestPornVideoScraper — przeniesiony do ALL_BROWSE_SCRAPERS (browse-konwersja 2026-06-22,
    # user 1da0375e: search-driven nie brał feedu "latest" → stary zestaw w apce).
    # LatestLeaksScraper — wyłączony 2026-05-12 (source quality report): 16,438 scen, 0.0%
    # canonical match. Slug-concat tytuły, brak studio/duration/date signali. Solo orphany
    # usunięte (~15k scen).
    MyPornerLeakScraper,
    # Added 2026-05-12 (theporndude survey): jeden z 14 free tubes na liście który
    # zwraca consistent search results. KVS engine, slug-aware scene URLs. Mostly
    # orphan ingest (auto-screenshots, no canonical phash match — sprawdzone), ale
    # może łapać sceny popularnych performerów których jeszcze nie mamy w TPDB.
    # PornHat (pornhatcom) + PornDitt (porndittcom) — USUNIĘTE CAŁKOWICIE 2026-06-22
    # (user request). Orphan factories (0.2% / weak-signal canonical match), zastępujemy
    # lepszymi źródłami. Dane/pliki scraperów/extractory skasowane.
    # Special
    SxyPrnScraper,
    # PerverzijaScraper — przeniesiony do ALL_BROWSE_SCRAPERS (browse-konwersja 2026-06-22,
    # user request). Search `?s=` → 429, homepage JS-renderowane; browse przez WP REST API
    # (/wp-json/wp/v2/posts) daje tytuł/datę/thumb/studio(category)/tagi. Playback embed-iframe.
    # FpoxxxScraper — przeniesiony do ALL_BROWSE_SCRAPERS (browse-konwersja 2026-06-22,
    # user request). fpo.xxx to KVS, nie WordPress → search `?s=` zwracał 0; browse z
    # `/new-<n>/` daje listing tile (tytuł/thumb/duration). Playback i tak phone-side (KVS).
]

# Browse-mode scrapers — iterują `latest-vids` listing zamiast search-by-performer.
# Phash thumbnail fingerprint (waga 0.40 w composite scoring) auto-mergeuje do
# canonical (TPDB/StashDB) gdy tube hot-linkuje studio thumbnail. Schedulowane
# raz dziennie, pages 1-5. Patrz `_browse_base.BaseBrowseScraper` +
# `app/scheduler/browse_latest.py`.
#
# **Pilot results (2026-05-12):**
#   - ShyfapScraper: 0/23 match (0%) — robi własne thumbnails ≠ canonical
#     (phash Hamming 12-16). Plus rebranduje tytuły. **Wyłączony.**
#   - FreshpornoScraper: 39/59 match (66%) — hot-linkuje studio thumbnaile
#     (phash Hamming 0). Oryginalne tytuły + channels=studio 1:1. **Aktywny.**
from app.connectors.direct_scrapers.freshporno import FreshpornoScraper  # noqa: E402
from app.connectors.direct_scrapers.porn00 import Porn00Scraper  # noqa: E402
from app.connectors.direct_scrapers.porndoe import PornDoeScraper  # noqa: E402
from app.connectors.direct_scrapers.pornxp import PornXPScraper  # noqa: E402
from app.connectors.direct_scrapers.shyfap import ShyfapScraper  # noqa: E402, F401
from app.connectors.direct_scrapers.yesporn import YesPornVipScraper  # noqa: E402
from app.connectors.direct_scrapers.fullmovies import FullmoviesScraper  # noqa: E402
from app.connectors.direct_scrapers.hdporngg import HDPornGGScraper  # noqa: E402
from app.connectors.direct_scrapers.neporn import NepornScraper  # noqa: E402
from app.connectors.direct_scrapers.superporn import SuperpornScraper  # noqa: E402
from app.connectors.direct_scrapers.eporner_api import EpornerApiScraper  # noqa: E402
from app.connectors.direct_scrapers.xvideos_browse import XVideosBrowseScraper  # noqa: E402

ALL_BROWSE_SCRAPERS: list[type[BaseBrowseScraper]] = [
    PerverzijaScraper,
    PornDishScraper,
    # Browse równolegle do istniejącego search scrapera (wzorzec xvideos/eporner):
    # search zostaje (pokrycie back-catalogu performerów), browse gwarantuje świeżość
    # wprost z feedu (watchdog 48h zamiast 168h). Konwersja 2026-06-24 (user request).
    PornTrexBrowseScraper,
    MyPornerLeakBrowseScraper,
    YouPornBrowseScraper,
    XnxxBrowseScraper,
    FreshpornoScraper,
    FpoxxxScraper,
    # LatestPornVideoScraper — browse od 2026-06-22 (user 1da0375e: search-driven
    # nie brał feedu "latest"). Listing card: tytuł (z embedded "<Studio> YY MM DD"),
    # thumb (studio+date w nazwie), category-* jako tag. Performerów listing nie ma
    # czysto (brak `actors-*`) → puste, dorabia canonical-merge. Playback: luluvid
    # iframe → extractor latestpornvideocom (_embed_iframe) → telefon resolwuje.
    LatestPornVideoScraper,
    # SiskaScraper — re-enabled 2026-06-20 jako browse (user fa4083a2). Search siski
    # zepsuty site-side (`?s=` ignoruje query), więc latest-browse z `/page/<n>/`.
    # Komplet metadanych z kafelka listingu (tytuł/duration/thumb/performer/studio/
    # kategoria). Playback: playmogo + luluvid → telefon resolwuje phone-side.
    SiskaScraper,
    # PornXPScraper — pilot 2026-05-17 (20 scen): studio 100%, performer 95%,
    # release_date 100%, duration 100%, stream_url 100%, phash 100%. Najlepsze
    # sygnały spośród browse-mode scraperów. Stream direct mp4 (sv.porn-xp.com)
    # 360/720 quality. Release year z `Released: <year>` na detail.
    PornXPScraper,
    # Porn00Scraper — pilot 2026-05-17 (16 scen): brak studio (0%) + brak release
    # date (0%) ALE performer 100%, duration 100%, stream_url 100% (KVS video_alt_url
    # 720p). Tytuł zachowuje studio prefix ("Studio Title - Scene Name") → title
    # fuzzy match (rapidfuzz token_set_ratio) może załapać canonical. Monitorować.
    Porn00Scraper,
    # PornDoeScraper — dołączony 2026-05-21 (theporndude audit). Każda scena ma
    # kompletny JSON-LD VideoObject: title + uploadDate + duration + named studio
    # (producer/publisher) + named performers (actor[]) + thumbnail. Najbogatsze
    # strukturalne metadane spośród browse scraperów — composite fuzzy match ma
    # komplet sygnałów. Phash hit-rate niski (własne crop-thumbnaile), studio +
    # performer + date + duration nadrabiają.
    PornDoeScraper,
    # YesPornVipScraper — dołączony 2026-05-27 (user audit). JSON-LD VideoObject
    # + `<meta property="video:duration|release_date|tag">` per scena (Goon ma
    # duration w sekundach gotowe + ISO 8601 release_date z timezone). Studio +
    # performerzy z `btn gold` linków (`/channels/<slug>/` + `/models/<slug>/`).
    # 941k organic monthly (SE Ranking, comparable z porndoe 731k / porntrex 790k).
    # Scraper-of-paysites (DogFart / HardX / TeamSkeet / Vixen) — wysokie expected
    # canonical match dla studio scenes. Korekta: theporndude scorecard rank 26
    # ('yespornvip.com', score -0.5, auth wall) dotyczył **innej domeny** — pdude.link
    # redirect do porndudecams affiliate. Prawdziwa kanoniczna domena to TLD `.vip`.
    YesPornVipScraper,
    # FullmoviesScraper + HDPornGGScraper — dołączone 2026-06-01. KVS engine (sponsor_groups
    # stack, `/videos/<slug>/` + `/latest-updates/`). Studio teraz z PREFIKSU tytułu
    # ("Studio - Scene") — sidebar `/networks/` listował WSZYSTKIE sieci, więc pierwszy match
    # zawsze Brazzers (mis-attribution, dlatego nigdy nie były włączone). Niosą paysite studio
    # content (TeamSkeet/Dad Crush/Brazzers/...) z title+performer+duration → composite fuzzy.
    # Nawet bez canonical match: grywalny content z inferred tagami (mission: daily tagged ingest).
    FullmoviesScraper,
    HDPornGGScraper,
    # EpornerApiScraper — dołączony 2026-06-03 (Faza 2b alternatywa). eporner detail to
    # JS-heavy KVS bez SSR metadanych (jak porntrex/hqporner — odrzucone), ALE eporner ma
    # publiczne JSON API (api/v2/video/search): 1 call = 100 filmów z title+length_sec+
    # keywords+added+thumb. ~100k filmów, deep-crawl przez crawl_page() (API, bez detail-fetch).
    EpornerApiScraper,
    # XVideosBrowseScraper — dołączony 2026-06-03. SSR JSON-LD (duration/title/uploadDate)
    # + page-parse /models/ (performerzy) + /tags/. Sample: median ~10.5min, 93% ≥3min.
    # Mega-katalog ~13M → deep_crawl._PAGE_CAP["xvideoscom"]=1800 (~50k najnowszych), nie
    # full-crawl. (youporn pominięty — JSON-LD bez actor/keywords, scene-perf/tagi = nav A-Z.)
    XVideosBrowseScraper,
    # HQFapScraper / FourK69Scraper — USUNIĘTE CAŁKOWICIE 2026-06-25. Oba PlayTube CMS;
    # disabled 2026-06-22 gdy playback padł, re-check 2026-06-25 potwierdził że CAŁA
    # biblioteka CDN znikła: wide-sample przez pełny zakres id (hqfap 0/80 real, 4k69
    # 0/40 real) — każda scena serwuje stały `/upload/videos/video_down.mp4` "server
    # down" stub, nie realny plik. Dane (28k solo-orphan scen + 46k sources) skasowane
    # z DB, pliki scraperów/extractorów i wpisy w _REGISTRY usunięte.
    # NepornScraper — dołączony 2026-06-10 (user request). KVS engine (jak freshporno/
    # porn00), /latest-updates/N/. JSON-LD (title+desc+uploadDate+thumb) + video:duration
    # meta + /models/ performerzy + /categories/ tagi. Brak studio (tytuł bywa
    # "- HardX Update - ..." — fuzzy match po tytule). Resolve server-side _kvs,
    # finalny remote_control.php portable cross-IP.
    NepornScraper,
    # SuperpornScraper — dołączony 2026-06-10 (user request). superporn blokuje VPS IP
    # twardym CF 403 (każda impersonacja TLS), więc ingest HTML idzie przez Bright Data
    # ISP proxy (BRIGHTDATA_PROXY_URL, ryczałt nie per-GB). Pierwszy scraper z proxy — `_proxy` w
    # _browse_base. JSON-LD (title+desc+uploadDate+thumb+duration) + chipy pornstar/
    # kategorie. Playback IP-bound → WebView (extractor superporncom → _vps_blocked_fallback).
    # Bez proxy: scraper no-op (pusty iterator).
    SuperpornScraper,
    # porntrex/hqporner/youporn — NIE: KVS/JS bez SSR duration → niewidoczne orphany (2026-06-03).
    # ShyfapScraper — wyłączony 2026-05-12 (pilot fail, 0% match — orphan factory).
]

__all__ = [
    "BaseDirectTubeScraper",
    "BaseBrowseScraper",
    "ALL_DIRECT_SCRAPERS",
    "ALL_BROWSE_SCRAPERS",
]
