"""
Tests for citation formatter error handling and malformed input scenarios.
"""

from local_deep_research.text_optimization.citation_formatter import (
    CitationFormatter,
    CitationMode,
)


class TestCitationErrorHandling:
    """Test error handling and resilience of citation formatter."""

    def test_malformed_citation_brackets(self):
        """Test handling of malformed citation brackets."""
        content = """# Research Report

Good citation [1], broken citation [2, missing citation ]3[,
reversed [4[ and double [[5]].

## Sources

[1] Good Paper
URL: https://example.com/1

[2] Second Paper
URL: https://example.com/2

[3] Third Paper
URL: https://example.com/3

[4] Fourth Paper
URL: https://example.com/4

[5] Fifth Paper
URL: https://example.com/5"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Good citations should be formatted
        assert "[example.com]" in result

        # Malformed citations should be left as-is
        assert "[2," in result  # Broken bracket
        assert "]3[" in result  # Reversed brackets
        assert "[4[" in result  # Double opening

    def test_invalid_citation_numbers(self):
        """Test handling of invalid citation numbers."""
        content = """# Research Report

Valid [1], invalid [0], [999], [-1], [abc], [1.5], [ 2 ].

## Sources

[1] Only Valid Source
URL: https://example.com/valid

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

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Valid citation should be formatted
        assert "[[example.com]](https://example.com/valid)" in result

        # Invalid citations should remain
        assert "[0]" in result
        assert "[999]" in result
        assert "[-1]" in result
        assert "[abc]" in result
        assert "[1.5]" in result

        # Citation with spaces might be processed
        # body = result.split("## Sources")[0]
        # [ 2 ] with spaces is an edge case - formatter might or might not handle it

    def test_circular_and_self_referencing(self):
        """Test handling of circular references in sources."""
        content = """# Research Report

Citation [1] refers to [2].

## Sources

[1] First Paper [2]
URL: https://first.com

[2] Second Paper [1]
URL: https://second.com"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Should format main text citations
        assert "[first.com]" in result
        assert "[second.com]" in result

        # Should not format citations within source descriptions
        sources_section = result.split("## Sources")[1]
        assert "[1] First Paper [2]" in sources_section
        assert "[2] Second Paper [1]" in sources_section

    def test_missing_source_numbers(self):
        """Test handling when source numbers are missing."""
        content = """# Research Report

Citations [1], [2], [3].

## Sources

[1] First Paper
URL: https://first.com

[3] Third Paper (note: [2] is missing)
URL: https://third.com"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Existing sources should be formatted
        assert "[first.com]" in result
        assert "[third.com]" in result

        # Missing source [2] should remain as-is
        assert "[2]" in result

    def test_duplicate_source_numbers(self):
        """Test handling of duplicate source numbers."""
        content = """# Research Report

Citations [1] and another [1].

## Sources

[1] First Paper
URL: https://first.com

[1] Duplicate Paper
URL: https://duplicate.com

[2] Normal Paper
URL: https://second.com"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Should handle duplicates (typically takes first occurrence)
        # The specific behavior depends on implementation
        assert "[first.com]" in result or "[duplicate.com]" in result

    def test_sources_without_numbers(self):
        """Test handling of sources without proper numbering."""
        content = """# Research Report

Citation [1].

## Sources

[1] Proper Source
URL: https://proper.com

Missing Number Source
URL: https://missing.com

[] Empty Brackets
URL: https://empty.com

[a] Letter Instead
URL: https://letter.com"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Properly numbered source should work
        assert "[proper.com]" in result

        # Improperly formatted sources should be ignored
        assert "[missing.com]" not in result
        assert "[empty.com]" not in result
        assert "[letter.com]" not in result

    def test_nested_brackets_and_escaping(self):
        """Test handling of nested brackets and escaped characters."""
        content = r"""# Research Report

Normal [1], escaped \[2\], nested [[3]], and markdown [link](url) [4].

## Sources

[1] First
URL: https://first.com

[2] Second
URL: https://second.com

[3] Third
URL: https://third.com

[4] Fourth
URL: https://fourth.com"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Normal citation should work
        assert "[first.com]" in result

        # Escaped brackets should be preserved
        assert r"\[2\]" in result

        # Markdown links should not interfere
        assert "[link](url)" in result

    def test_malformed_urls(self):
        """Test handling of malformed URLs in sources."""
        content = """# Research Report

Citations [1] [2] [3] [4] [5].

## Sources

[1] No Protocol
URL: example.com/paper

[2] Invalid Protocol
URL: htp://example.com/paper

[3] Just Domain
URL: https://example.com

[4] Spaces in URL
URL: https://example.com/my paper.pdf

[5] Missing URL Label
https://example.com/nolabel"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Well-formed URLs should work
        assert result.count("[example.com]") >= 1

        # Malformed URLs might not be processed correctly
        # The specific behavior depends on URL parsing implementation

    def test_special_markdown_interference(self):
        """Test that special markdown doesn't interfere with citations."""
        content = """# Research Report

**Bold [1]**, *italic [2]*, `code [3]`, ~~strike [4]~~.

> Quote [5]
> Multiple lines

| Table | Cell [6] |
|-------|----------|
| Data  | [7]      |

## Sources

[1] Bold Source
URL: https://bold.com

[2] Italic Source
URL: https://italic.com

[3] Code Source
URL: https://code.com

[4] Strike Source
URL: https://strike.com

[5] Quote Source
URL: https://quote.com

[6] Table Source
URL: https://table.com

[7] Cell Source
URL: https://cell.com"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # All citations should be formatted despite markdown
        domains = [
            "bold.com",
            "italic.com",
            "code.com",
            "strike.com",
            "quote.com",
            "table.com",
            "cell.com",
        ]

        for domain in domains:
            assert f"[{domain}]" in result

    def test_extremely_long_content(self):
        """Test handling of very long documents."""
        # Create a document with many citations
        citations = []
        sources = []

        for i in range(1, 101):
            citations.append(f"Citation [{i}]")
            sources.append(f"""[{i}] Source {i}
URL: https://example{i}.com/paper""")

        content = f"""# Large Document

{" ".join(citations)}

## Sources

{chr(10).join(sources)}"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_ID_HYPERLINKS)
        result = formatter.format_document(content)

        # Should handle all citations
        for i in range(1, 101):
            assert f"[example{i}.com" in result

    def test_source_url_edge_cases(self):
        """Test edge cases in URL detection within sources."""
        content = """# Research Report

Citations [1] [2] [3].

## Sources

[1] Multiple URLs
URL: https://first.com
Also available at: https://mirror.com

[2] URL in Middle
Paper Title URL: https://second.com more text

[3] Commented URL
# URL: https://commented.com
URL: https://actual.com"""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Should pick up the first URL after "URL:"
        assert "[first.com]" in result
        assert "[commented.com]" not in result

        # URLs with text after them on the same line are not captured
        # This is a known limitation of the current regex pattern
        assert "[second.com]" not in result

        # URL after a comment line is also not captured
        # The formatter only captures URLs immediately after the source title
        assert "[actual.com]" not in result

    def test_mixed_citation_styles(self):
        """Test documents with mixed citation styles."""
        content = """# Research Report

IEEE style [1], parenthetical (Smith, 2023), footnote[^1], and [2].

## Sources

[1] First Paper
URL: https://first.com

[2] Second Paper
URL: https://second.com

[^1]: This is a footnote, not a citation source."""

        formatter = CitationFormatter(mode=CitationMode.DOMAIN_HYPERLINKS)
        result = formatter.format_document(content)

        # Should only format numbered citations
        assert "[first.com]" in result
        assert "[second.com]" in result

        # Other citation styles should remain
        assert "(Smith, 2023)" in result
        assert "[^1]" in result
