"""Tests for huntpdf.download."""

from pathlib import Path

import httpx
import pytest
import respx

from huntpdf.download import download_pdf
from huntpdf.errors import DownloadFailed, PDFNotFound

PDF_URL = "https://example.com/paper.pdf"
FAKE_PDF = b"%PDF-1.4 fake content"


@respx.mock
def test_successful_pdf_download(tmp_path: Path):
    respx.get(PDF_URL).mock(
        return_value=httpx.Response(
            200,
            content=FAKE_PDF,
            headers={"content-type": "application/pdf"},
        )
    )
    out = tmp_path / "out.pdf"
    result = download_pdf(PDF_URL, out)
    assert result == out
    assert out.read_bytes() == FAKE_PDF


@respx.mock
def test_404_raises_pdf_not_found_without_browser(tmp_path: Path, monkeypatch):
    respx.get(PDF_URL).mock(return_value=httpx.Response(404))
    browser_called = False

    def mock_browser(url, output):
        nonlocal browser_called
        browser_called = True
        return output

    monkeypatch.setattr(
        "huntpdf.download.fetch_pdf_browser_sync", mock_browser
    )
    with pytest.raises(PDFNotFound):
        download_pdf(PDF_URL, tmp_path / "out.pdf")
    assert not browser_called


@respx.mock
def test_wrong_content_type_triggers_browser_fallback(
    tmp_path: Path, monkeypatch
):
    respx.get(PDF_URL).mock(
        return_value=httpx.Response(
            200,
            content=b"<html>not a pdf</html>",
            headers={"content-type": "text/html"},
        )
    )
    out = tmp_path / "out.pdf"

    def mock_browser(url, output):
        output.write_bytes(FAKE_PDF)
        return output

    monkeypatch.setattr(
        "huntpdf.download.fetch_pdf_browser_sync", mock_browser
    )
    result = download_pdf(PDF_URL, out)
    assert result == out
    assert out.read_bytes() == FAKE_PDF


@respx.mock
def test_browser_fallback_success_after_http_error(
    tmp_path: Path, monkeypatch
):
    respx.get(PDF_URL).mock(return_value=httpx.Response(500))
    out = tmp_path / "out.pdf"

    def mock_browser(url, output):
        output.write_bytes(FAKE_PDF)
        return output

    monkeypatch.setattr(
        "huntpdf.download.fetch_pdf_browser_sync", mock_browser
    )
    result = download_pdf(PDF_URL, out)
    assert result == out
    assert out.read_bytes() == FAKE_PDF


@respx.mock
def test_both_methods_fail_raises_download_failed(
    tmp_path: Path, monkeypatch
):
    respx.get(PDF_URL).mock(return_value=httpx.Response(500))

    def mock_browser(url, output):
        raise RuntimeError("browser also failed")

    monkeypatch.setattr(
        "huntpdf.download.fetch_pdf_browser_sync", mock_browser
    )
    with pytest.raises(DownloadFailed):
        download_pdf(PDF_URL, tmp_path / "out.pdf")
