"""Functional tests for BibDoiTool."""

from __future__ import annotations

from unittest.mock import MagicMock, patch

from axm.tools.base import ToolResult

from axm_bib.models import BibEntry
from axm_bib.tools.bib_doi import BibDoiTool
from tests.conftest import SAMPLE_CROSSREF_BIBTEX, SAMPLE_DOI


class TestBibDoiTool:
    """BibDoiTool E2E (mocked HTTP)."""

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

    @patch("axm_bib.tools.bib_doi.BibPipeline")
    def test_execute_valid_doi(self, mock_pipeline_class: MagicMock) -> None:
        """Valid DOI → success with bibtex string."""
        mock_pipeline = mock_pipeline_class.return_value
        mock_pipeline.resolve_bibtex.return_value = BibEntry(
            key="smith2024deep",
            entry_type="article",
            raw=SAMPLE_CROSSREF_BIBTEX,
            doi=SAMPLE_DOI,
            title="Deep Learning for Citation Analysis",
            authors=["John Smith", "Jane Doe"],
            year=2024,
        )

        tool = BibDoiTool()
        result = tool.execute(doi=SAMPLE_DOI)
        assert isinstance(result, ToolResult)
        assert result.success is True
        assert "bibtex" in result.data
        assert "@article" in result.data["bibtex"]

    @patch("axm_bib.tools.bib_doi.BibPipeline")
    def test_execute_key_format(self, mock_pipeline_class: MagicMock) -> None:
        """Key in result.data matches smith2024deep format."""
        mock_pipeline = mock_pipeline_class.return_value
        mock_pipeline.resolve_bibtex.return_value = BibEntry(
            key="smith2024deep",
            entry_type="article",
            raw=SAMPLE_CROSSREF_BIBTEX,
            doi=SAMPLE_DOI,
        )

        tool = BibDoiTool()
        result = tool.execute(doi=SAMPLE_DOI)
        key = result.data["key"]
        assert key.isalnum()
        assert key == key.lower()

    @patch("axm_bib.tools.bib_doi.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.resolve_bibtex.side_effect = Exception("Invalid DOI")

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

    @patch("axm_bib.tools.bib_doi.BibPipeline")
    def test_execute_empty_doi(self, mock_pipeline_class: MagicMock) -> None:
        """Empty DOI → success=False, error set."""
        tool = BibDoiTool()
        result = tool.execute(doi="")
        assert result.success is False
        assert result.error is not None
