"""Tests for RISExporter."""

import pytest
from unittest.mock import patch


class TestRISExporterProperties:
    """Tests for RISExporter properties."""

    def test_format_name_is_ris(self):
        """Test that format_name is 'ris'."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        exporter = RISExporter()

        assert exporter.format_name == "ris"

    def test_file_extension_is_ris(self):
        """Test that file_extension is '.ris'."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        exporter = RISExporter()

        assert exporter.file_extension == ".ris"

    def test_mimetype_is_correct(self):
        """Test that mimetype is correct for RIS."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        exporter = RISExporter()

        assert exporter.mimetype == "text/plain"


class TestRISExporterExport:
    """Tests for RISExporter.export method."""

    @pytest.fixture
    def exporter(self):
        """Create RISExporter instance."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        return RISExporter()

    @pytest.fixture
    def markdown_with_sources(self):
        """Markdown content with sources for RIS export."""
        return """# Research Report

This is a test report with sources.

## Sources

[1] First Source Title
URL: https://example.com/source1

[2] Second Source Title
URL: https://example.com/source2
"""

    def test_returns_export_result(self, exporter, markdown_with_sources):
        """Test that export returns ExportResult."""
        from local_deep_research.exporters import ExportResult

        result = exporter.export(markdown_with_sources)

        assert isinstance(result, ExportResult)

    def test_result_content_is_bytes(self, exporter, markdown_with_sources):
        """Test that result content is bytes."""
        result = exporter.export(markdown_with_sources)

        assert isinstance(result.content, bytes)

    def test_result_filename_uses_title(self, exporter, markdown_with_sources):
        """Test that filename uses provided title."""
        from local_deep_research.exporters import ExportOptions

        options = ExportOptions(title="My Research Report")
        result = exporter.export(markdown_with_sources, options)

        assert "My_Research_Report" in result.filename
        assert result.filename.endswith(".ris")

    def test_result_filename_default_when_no_title(
        self, exporter, markdown_with_sources
    ):
        """Test that filename uses default when no title."""
        result = exporter.export(markdown_with_sources)

        assert "research_report" in result.filename
        assert result.filename.endswith(".ris")

    def test_result_mimetype_is_correct(self, exporter, markdown_with_sources):
        """Test that result mimetype is correct."""
        result = exporter.export(markdown_with_sources)

        assert result.mimetype == "text/plain"

    def test_handles_empty_markdown(self, exporter):
        """Test handling of empty markdown."""
        result = exporter.export("")

        assert isinstance(result.content, bytes)

    def test_handles_markdown_without_sources(self, exporter, simple_markdown):
        """Test handling of markdown without sources section."""
        result = exporter.export(simple_markdown)

        assert isinstance(result.content, bytes)

    def test_handles_special_characters(
        self, exporter, markdown_with_special_chars
    ):
        """Test handling of special characters."""
        result = exporter.export(markdown_with_special_chars)

        assert isinstance(result.content, bytes)

    def test_logs_ris_size(self, exporter, markdown_with_sources):
        """Test that RIS size is logged."""
        with patch(
            "local_deep_research.exporters.ris_exporter.logger"
        ) as mock_logger:
            exporter.export(markdown_with_sources)

            mock_logger.info.assert_called_once()
            call_args = mock_logger.info.call_args[0][0]
            assert "Generated RIS" in call_args
            assert "bytes" in call_args


class TestRISExporterOutput:
    """Tests for RIS format output structure."""

    @pytest.fixture
    def exporter(self):
        """Create RISExporter instance."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        return RISExporter()

    @pytest.fixture
    def markdown_with_sources(self):
        """Markdown content with sources for RIS export."""
        return """# Research Report

This is a test report with sources.

## Sources

[1] First Source Title
URL: https://example.com/source1

[2] Second Source Title
URL: https://example.com/source2
"""

    def test_ris_contains_type_tag(self, exporter, markdown_with_sources):
        """Test that RIS output contains TY (type) tag."""
        result = exporter.export(markdown_with_sources)
        content = result.content.decode("utf-8")

        # RIS entries start with TY tag
        assert "TY  -" in content

    def test_ris_contains_end_record(self, exporter, markdown_with_sources):
        """Test that RIS output contains ER (end record) tag."""
        result = exporter.export(markdown_with_sources)
        content = result.content.decode("utf-8")

        # RIS entries end with ER tag
        assert "ER  -" in content

    def test_ris_contains_url_for_sources(
        self, exporter, markdown_with_sources
    ):
        """Test that RIS output contains URL when sources have URLs."""
        result = exporter.export(markdown_with_sources)
        content = result.content.decode("utf-8")

        # Check for URL tag (UR) or the actual URL
        # Note: actual presence depends on the legacy exporter implementation
        assert isinstance(content, str)


class TestRISExporterContentSizeLimit:
    """Tests for content size limit enforcement."""

    @pytest.fixture
    def exporter(self):
        """Create RISExporter instance."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        return RISExporter()

    def test_raises_error_for_oversized_content(self, exporter):
        """Test that ValueError is raised for content exceeding size limit."""
        from local_deep_research.exporters.base import BaseExporter

        MAX_CONTENT_SIZE = BaseExporter.MAX_CONTENT_SIZE

        # Create content that exceeds the limit
        oversized_content = "x" * (MAX_CONTENT_SIZE + 1)

        with pytest.raises(ValueError) as exc_info:
            exporter.export(oversized_content)

        assert "exceeds maximum size" in str(exc_info.value)

    def test_accepts_content_at_limit(self, exporter):
        """Test that content at exactly the limit is accepted."""
        from local_deep_research.exporters.base import BaseExporter

        MAX_CONTENT_SIZE = BaseExporter.MAX_CONTENT_SIZE

        # Create content at exactly the limit
        content_at_limit = "x" * MAX_CONTENT_SIZE

        # Mock the legacy exporter to avoid processing large content
        with patch.object(
            exporter._legacy, "export_to_ris", return_value="TY  - WEB\nER  -"
        ):
            result = exporter.export(content_at_limit)
            assert isinstance(result.content, bytes)

    def test_accepts_content_under_limit(self, exporter, simple_markdown):
        """Test that content under the limit is accepted."""
        result = exporter.export(simple_markdown)

        assert isinstance(result.content, bytes)


class TestRISExporterErrorHandling:
    """Tests for error handling in RISExporter."""

    @pytest.fixture
    def exporter(self):
        """Create RISExporter instance."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        return RISExporter()

    def test_logs_exception_on_error(self, exporter):
        """Test that exceptions are logged."""
        with patch.object(
            exporter._legacy,
            "export_to_ris",
            side_effect=Exception("Test error"),
        ):
            with patch(
                "local_deep_research.exporters.ris_exporter.logger"
            ) as mock_logger:
                with pytest.raises(Exception):
                    exporter.export("test")

                mock_logger.exception.assert_called_once()


class TestRISExporterIntegration:
    """Integration tests for RISExporter with ExporterRegistry."""

    def test_registered_in_registry(self):
        """Test that RISExporter is registered in the registry."""
        from local_deep_research.exporters import ExporterRegistry

        assert ExporterRegistry.is_format_supported("ris")

    def test_can_get_from_registry(self):
        """Test that RISExporter can be retrieved from registry."""
        from local_deep_research.exporters import ExporterRegistry
        from local_deep_research.exporters.ris_exporter import RISExporter

        exporter = ExporterRegistry.get_exporter("ris")

        assert isinstance(exporter, RISExporter)

    def test_export_via_registry(self, simple_markdown):
        """Test export via registry lookup."""
        from local_deep_research.exporters import ExporterRegistry

        exporter = ExporterRegistry.get_exporter("ris")
        result = exporter.export(simple_markdown)

        assert isinstance(result.content, bytes)
        assert result.filename.endswith(".ris")


class TestRISExporterFilenameTruncation:
    """Tests for filename truncation with long titles."""

    @pytest.fixture
    def exporter(self):
        """Create RISExporter instance."""
        from local_deep_research.exporters.ris_exporter import RISExporter

        return RISExporter()

    def test_filename_truncated_to_50_chars(self, exporter, simple_markdown):
        """Test that filename is truncated when title exceeds 50 chars."""
        from local_deep_research.exporters import ExportOptions

        # Title with more than 50 characters
        long_title = "A" * 60
        options = ExportOptions(title=long_title)
        result = exporter.export(simple_markdown, options)

        # Filename should be truncated to 50 chars + extension
        filename_without_ext = result.filename.rsplit(".", 1)[0]
        assert len(filename_without_ext) == 50
        assert result.filename.endswith(".ris")

    def test_filename_not_truncated_under_50_chars(
        self, exporter, simple_markdown
    ):
        """Test that filename is not truncated when under 50 chars."""
        from local_deep_research.exporters import ExportOptions

        title = "Short Title"
        options = ExportOptions(title=title)
        result = exporter.export(simple_markdown, options)

        assert "Short_Title" in result.filename
        assert result.filename.endswith(".ris")
