"""Tests for BioRxiv PDF downloader."""

from unittest.mock import Mock, patch


from local_deep_research.research_library.downloaders.biorxiv import (
    BioRxivDownloader,
)


class TestBioRxivDownloaderInit:
    """Tests for BioRxivDownloader initialization."""

    def test_initializes_with_default_timeout(self):
        """Should initialize with default timeout."""
        downloader = BioRxivDownloader()
        assert downloader.timeout == 30

    def test_initializes_with_custom_timeout(self):
        """Should accept custom timeout."""
        downloader = BioRxivDownloader(timeout=60)
        assert downloader.timeout == 60

    def test_creates_session(self):
        """Should create a requests session."""
        downloader = BioRxivDownloader()
        assert downloader.session is not None


class TestBioRxivDownloaderCanHandle:
    """Tests for can_handle method."""

    def test_handles_biorxiv_url(self):
        """Should handle biorxiv.org URLs."""
        downloader = BioRxivDownloader()
        assert downloader.can_handle(
            "https://www.biorxiv.org/content/10.1101/2024.01.01"
        )
        assert downloader.can_handle(
            "https://biorxiv.org/content/10.1101/2024.01.01"
        )

    def test_handles_medrxiv_url(self):
        """Should handle medrxiv.org URLs."""
        downloader = BioRxivDownloader()
        assert downloader.can_handle(
            "https://www.medrxiv.org/content/10.1101/2024.01.01"
        )
        assert downloader.can_handle(
            "https://medrxiv.org/content/10.1101/2024.01.01"
        )

    def test_rejects_other_urls(self):
        """Should reject non-biorxiv URLs."""
        downloader = BioRxivDownloader()
        assert not downloader.can_handle("https://arxiv.org/abs/1234.5678")
        assert not downloader.can_handle(
            "https://pubmed.ncbi.nlm.nih.gov/12345"
        )
        assert not downloader.can_handle("https://example.com/paper.pdf")

    def test_rejects_empty_url(self):
        """Should reject empty URLs."""
        downloader = BioRxivDownloader()
        assert not downloader.can_handle("")

    def test_rejects_none_url(self):
        """Should handle None URL gracefully."""
        downloader = BioRxivDownloader()
        # Should not raise, just return False
        try:
            result = downloader.can_handle(None)
            assert result is False
        except (TypeError, AttributeError):
            # Acceptable to raise for None
            pass


class TestBioRxivDownloaderConvertToPdfUrl:
    """Tests for _convert_to_pdf_url method."""

    def test_converts_content_url_to_pdf_url(self):
        """Should convert content URL to PDF URL."""
        downloader = BioRxivDownloader()
        url = "https://www.biorxiv.org/content/10.1101/2024.01.15.575123v1"
        pdf_url = downloader._convert_to_pdf_url(url)
        assert pdf_url is not None
        assert ".pdf" in pdf_url

    def test_handles_medrxiv_url(self):
        """Should handle medrxiv URLs."""
        downloader = BioRxivDownloader()
        url = "https://www.medrxiv.org/content/10.1101/2024.02.20.12345678v2"
        pdf_url = downloader._convert_to_pdf_url(url)
        assert pdf_url is not None


class TestBioRxivDownloaderDownload:
    """Tests for download method."""

    def test_handles_download_failure(self):
        """Should handle download failure gracefully."""
        downloader = BioRxivDownloader()

        with patch.object(
            downloader.session, "get", side_effect=Exception("Network error")
        ):
            result = downloader.download(
                "https://www.biorxiv.org/content/10.1101/2024.01.15.575123v1"
            )

        assert result is None

    def test_handles_404_response(self):
        """Should handle 404 response."""
        downloader = BioRxivDownloader()

        mock_response = Mock()
        mock_response.status_code = 404
        mock_response.raise_for_status = Mock(
            side_effect=Exception("404 Not Found")
        )

        with patch.object(
            downloader.session, "get", return_value=mock_response
        ):
            result = downloader.download(
                "https://www.biorxiv.org/content/10.1101/2024.01.15.575123v1"
            )

        assert result is None


class TestBioRxivDownloaderDownloadWithResult:
    """Tests for download_with_result method."""

    def test_returns_skip_reason_on_failure(self):
        """Should return skip_reason when download fails."""
        downloader = BioRxivDownloader()

        with patch.object(downloader, "_convert_to_pdf_url", return_value=None):
            result = downloader.download_with_result(
                "https://example.com/invalid"
            )

        assert result.is_success is False
        assert result.skip_reason is not None


class TestBioRxivDownloaderFetchAbstract:
    """Tests for _fetch_abstract_from_page method."""

    def test_handles_fetch_failure(self):
        """Should handle fetch failure gracefully."""
        downloader = BioRxivDownloader()

        with patch.object(
            downloader.session, "get", side_effect=Exception("Network error")
        ):
            abstract = downloader._fetch_abstract_from_page(
                "https://www.biorxiv.org/content/10.1101/test"
            )

        assert abstract is None
