import tempfile
import unittest
from pathlib import Path
from unittest import mock

from doc2md import ocr as ocr_mod
from doc2md.converter import ConversionError, image_to_markdown, pdf_to_markdown


def assert_normalized(test_case: unittest.TestCase, content: str) -> None:
    test_case.assertNotIn("\r", content)
    lines = content.split("\n")
    if content:
        test_case.assertTrue(content.endswith("\n"))
    for line in lines:
        test_case.assertEqual(line, line.rstrip())

    blank_run = 0
    for line in lines:
        if line == "":
            blank_run += 1
            test_case.assertLessEqual(blank_run, 2)
        else:
            blank_run = 0


class ConverterOcrTest(unittest.TestCase):
    def test_image_to_markdown_missing_dep_raises(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            img_path = Path(tmpdir) / "input.png"
            img_path.write_bytes(b"fake")
            ocr_mod._OCR_CACHE.clear()
            with mock.patch("doc2md.ocr._load_paddleocr", side_effect=ImportError("no")):
                with self.assertRaises(ConversionError):
                    image_to_markdown(img_path)

    def test_image_to_markdown_normalizes_output(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            img_path = Path(tmpdir) / "input.png"
            img_path.write_bytes(b"fake")
            raw_text = "Line 1  \r\n\r\n\r\nLine 2  \r\n"
            with mock.patch("doc2md.ocr.ocr_image", return_value=raw_text):
                output = image_to_markdown(img_path)
            assert_normalized(self, output)
            self.assertIn("Line 1", output)
            self.assertIn("Line 2", output)

    def test_pdf_to_markdown_ocr_auto_only_on_empty_text(self) -> None:
        with tempfile.TemporaryDirectory() as tmpdir:
            pdf_path = Path(tmpdir) / "input.pdf"
            pdf_path.write_bytes(b"%PDF-1.4\n")
            with mock.patch("doc2md.converter._extract_pdf_text", return_value="   \n"):
                with mock.patch("doc2md.ocr.ocr_pdf", return_value="OCR\r\n") as ocr_mock:
                    output = pdf_to_markdown(pdf_path, ocr_mode="auto")
                    self.assertEqual(output, "OCR\n")
                    ocr_mock.assert_called_once()

            with mock.patch("doc2md.converter._extract_pdf_text", return_value="Hello"):
                with mock.patch("doc2md.ocr.ocr_pdf") as ocr_mock:
                    output = pdf_to_markdown(pdf_path, ocr_mode="auto")
                    self.assertEqual(output, "Hello\n")
                    ocr_mock.assert_not_called()


if __name__ == "__main__":
    unittest.main()
