from __future__ import annotations

from pathlib import Path

import pytest

from worai.core.url_sources.models import UrlRecord, UrlSourceOptions
from worai.core.url_sources import resolver as mod
from worai.errors import UsageError


def test_dedupe_normalize_and_http_predicate() -> None:
    assert mod._dedupe([" a ", "", "a", "b"]) == ["a", "b"]
    assert mod._is_http_url("https://e.com") is True
    assert mod._is_http_url("ftp://e.com") is False

    rows = mod._normalize_records([
        UrlRecord(url=" "),
        UrlRecord(url="ftp://e.com"),
        UrlRecord(url="https://e.com", html="h"),
        UrlRecord(url="https://e.com"),
    ])
    assert len(rows) == 1
    assert rows[0].html == "h"

    compiled = mod._compile_url_regex(r"ok")
    assert compiled is not None and compiled.search("https://e.com/ok")
    assert mod._compile_url_regex(None) is None
    assert mod._compile_url_regex("  ") is None


def test_resolve_url_records_explicit_source_modes(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
    monkeypatch.setattr(mod, "resolve_ingest_settings", lambda **_k: type("I", (), {"source": "urls"})())
    with pytest.raises(UsageError, match="requires a local URL list file"):
        mod.resolve_url_records(UrlSourceOptions(source=str(tmp_path / "missing.txt"), ingest_source="urls"))

    p = tmp_path / "u.txt"
    p.write_text("https://e.com/a\n", encoding="utf-8")
    monkeypatch.setattr(mod, "load_urls_from_file", lambda _p: ["https://e.com/a"])
    rows = mod.resolve_url_records(UrlSourceOptions(source=str(p), ingest_source="urls"))
    assert rows[0].source_type == "file"

    monkeypatch.setattr(mod, "resolve_ingest_settings", lambda **_k: type("I", (), {"source": "sitemap"})())
    monkeypatch.setattr(mod, "load_urls_from_sitemap", lambda *_a, **_k: ["https://e.com/s"])
    rows = mod.resolve_url_records(UrlSourceOptions(source="https://e.com/sitemap.xml", ingest_source="sitemap"))
    assert rows[0].source_type == "sitemap"

    monkeypatch.setattr(mod, "resolve_ingest_settings", lambda **_k: type("I", (), {"source": "sheets"})())
    with pytest.raises(UsageError, match="requires a Google Spreadsheet"):
        mod.resolve_url_records(UrlSourceOptions(source="https://e.com/sitemap.xml", ingest_source="sheets", sheet_name="S"))

    monkeypatch.setattr(mod, "is_spreadsheet_source", lambda _s: True)
    with pytest.raises(UsageError, match="sheet-name is required"):
        mod.resolve_url_records(UrlSourceOptions(source="sheetid", ingest_source="sheets"))

    monkeypatch.setattr(mod, "load_urls_from_sheet", lambda *_a, **_k: ["https://e.com/a"])
    rows = mod.resolve_url_records(UrlSourceOptions(source="sheetid", ingest_source="sheets", sheet_name="S"))
    assert rows[0].source_type == "sheet"


def test_resolve_url_records_path_and_fallback(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
    monkeypatch.setattr(mod, "resolve_ingest_settings", lambda **_k: type("I", (), {"source": "auto"})())

    ttl = tmp_path / "x.ttl"
    ttl.write_text("", encoding="utf-8")
    monkeypatch.setattr(mod, "load_records_from_debug_cloud", lambda _s: [UrlRecord(url="https://e.com/d")])
    assert mod.resolve_url_records(UrlSourceOptions(source=str(ttl)))[0].url == "https://e.com/d"

    xml = tmp_path / "x.xml"
    xml.write_text("", encoding="utf-8")
    monkeypatch.setattr(mod, "load_urls_from_sitemap", lambda *_a, **_k: ["https://e.com/x"])
    assert mod.resolve_url_records(UrlSourceOptions(source=str(xml)))[0].source_type == "sitemap"

    txt = tmp_path / "x.txt"
    txt.write_text("", encoding="utf-8")
    monkeypatch.setattr(mod, "load_urls_from_file", lambda _p: ["https://e.com/f"])
    assert mod.resolve_url_records(UrlSourceOptions(source=str(txt)))[0].source_type == "file"

    rows = mod.resolve_url_records(UrlSourceOptions(source="file:///tmp/sitemap.xml"))
    assert rows[0].source_type == "sitemap"

    with pytest.raises(UsageError, match="SOURCE must be"):
        mod.resolve_url_records(UrlSourceOptions(source="not-a-source"))


def test_resolve_url_records_invalid_url_regex(monkeypatch: pytest.MonkeyPatch) -> None:
    monkeypatch.setattr(mod, "resolve_ingest_settings", lambda **_k: type("I", (), {"source": "sitemap"})())
    monkeypatch.setattr(mod, "load_urls_from_sitemap", lambda *_a, **_k: ["https://e.com/a"])

    with pytest.raises(UsageError, match="Invalid --url-regex pattern"):
        mod.resolve_url_records(
            UrlSourceOptions(
                source="https://e.com/sitemap.xml",
                ingest_source="sitemap",
                url_regex="(",
            )
        )
