"""Functional tests for BibPdfTool."""

from __future__ import annotations

from pathlib import Path
from unittest.mock import MagicMock, patch

from axm.tools.base import ToolResult

from axm_bib.models import DownloadResult
from axm_bib.tools.bib_pdf import BibPdfTool
from tests.conftest import SAMPLE_DOI


class TestBibPdfTool:
    """BibPdfTool E2E (mocked HTTP)."""

    def test_name_property(self) -> None:
        """Tool name is 'bib_pdf'."""
        tool = BibPdfTool()
        assert tool.name == "bib_pdf"

    @patch("axm_bib.tools.bib_pdf.BibPipeline")
    def test_execute_downloads_pdf(
        self, mock_pipeline_class: MagicMock, tmp_path: Path
    ) -> None:
        """Successful download → result.data['path'] file exists."""
        pdf_path = tmp_path / "smith2024deep.pdf"
        pdf_path.write_bytes(b"%PDF-1.4 content")

        mock_pipeline = mock_pipeline_class.return_value
        mock_pipeline.download_pdf.return_value = DownloadResult(
            doi=SAMPLE_DOI,
            path=str(pdf_path),
            size_bytes=16,
            is_open_access=True,
        )

        tool = BibPdfTool()
        result = tool.execute(ref=SAMPLE_DOI)
        assert isinstance(result, ToolResult)
        assert result.success is True
        assert "path" in result.data
        assert Path(result.data["path"]).exists()

    @patch("axm_bib.tools.bib_pdf.BibPipeline")
    def test_execute_closed_access(self, mock_pipeline_class: MagicMock) -> None:
        """Closed-access → success=True but path is None."""
        mock_pipeline = mock_pipeline_class.return_value
        mock_pipeline.download_pdf.return_value = None

        tool = BibPdfTool()
        result = tool.execute(ref="10.1234/closed")
        assert result.success is True
        assert result.data.get("path") is None
        assert result.data.get("is_open_access") is False

    @patch("axm_bib.tools.bib_pdf.BibPipeline")
    def test_execute_invalid_doi(self, mock_pipeline_class: MagicMock) -> None:
        """Invalid DOI → success=False."""
        mock_pipeline = mock_pipeline_class.return_value
        mock_pipeline.download_pdf.side_effect = Exception("Invalid DOI")

        tool = BibPdfTool()
        result = tool.execute(ref="not-a-doi")
        assert result.success is False
        assert result.error is not None

    @patch("axm_bib.tools.bib_pdf.BibPipeline")
    def test_execute_download_failure(self, mock_pipeline_class: MagicMock) -> None:
        """Network error during download → success=False."""
        mock_pipeline = mock_pipeline_class.return_value
        mock_pipeline.download_pdf.side_effect = ConnectionError("timeout")

        tool = BibPdfTool()
        result = tool.execute(ref=SAMPLE_DOI)
        assert result.success is False
        assert result.error is not None
