"""Tests for LaTeXExporter."""

import pytest
from unittest.mock import patch


class TestLaTeXExporterProperties:
    """Tests for LaTeXExporter properties."""

    def test_format_name_is_latex(self):
        """Test that format_name is 'latex'."""
        from local_deep_research.exporters.latex_exporter import LaTeXExporter

        exporter = LaTeXExporter()

        assert exporter.format_name == "latex"

    def test_file_extension_is_tex(self):
        """Test that file_extension is '.tex'."""
        from local_deep_research.exporters.latex_exporter import LaTeXExporter

        exporter = LaTeXExporter()

        assert exporter.file_extension == ".tex"

    def test_mimetype_is_correct(self):
        """Test that mimetype is correct for LaTeX."""
        from local_deep_research.exporters.latex_exporter import LaTeXExporter

        exporter = LaTeXExporter()

        assert exporter.mimetype == "text/plain"


class TestLaTeXExporterExport:
    """Tests for LaTeXExporter.export method."""

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

        return LaTeXExporter()

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

        result = exporter.export(simple_markdown)

        assert isinstance(result, ExportResult)

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

        assert isinstance(result.content, bytes)

    def test_result_content_is_valid_latex(self, exporter, simple_markdown):
        """Test that result content is valid LaTeX."""
        result = exporter.export(simple_markdown)

        # LaTeX documents typically start with documentclass or contain common LaTeX commands
        content_str = result.content.decode("utf-8")
        # Should contain LaTeX-like structure (backslash commands or plain text)
        assert len(content_str) > 0

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

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

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

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

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

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

        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_with_all_features(
        self, exporter, sample_markdown
    ):
        """Test handling of markdown with tables, code, lists."""
        result = exporter.export(sample_markdown)

        assert isinstance(result.content, bytes)
        assert len(result.content) > 0

    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_handles_large_markdown(self, exporter):
        """Test handling of large markdown content."""
        large_content = "# Large Document\n\n"
        large_content += ("This is a paragraph. " * 100 + "\n\n") * 50

        result = exporter.export(large_content)

        assert isinstance(result.content, bytes)
        assert len(result.content) > 1000

    def test_logs_latex_size(self, exporter, simple_markdown):
        """Test that LaTeX size is logged."""
        with patch(
            "local_deep_research.exporters.latex_exporter.logger"
        ) as mock_logger:
            exporter.export(simple_markdown)

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


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

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

        return LaTeXExporter()

    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_latex",
            return_value="\\documentclass{article}",
        ):
            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 TestLaTeXExporterErrorHandling:
    """Tests for error handling in LaTeXExporter."""

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

        return LaTeXExporter()

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

                mock_logger.exception.assert_called_once()


class TestLaTeXExporterIntegration:
    """Integration tests for LaTeXExporter with ExporterRegistry."""

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

        assert ExporterRegistry.is_format_supported("latex")

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

        exporter = ExporterRegistry.get_exporter("latex")

        assert isinstance(exporter, LaTeXExporter)

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

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

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


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

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

        return LaTeXExporter()

    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(".tex")

    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(".tex")
