"""
Integration Tests (End-to-End).
"""

import unittest
import importlib.util
import shutil
from pathlib import Path
from normadocs.preprocessor import MarkdownPreprocessor
from normadocs.pandoc_client import PandocRunner
from normadocs.docx_formatter import APADocxFormatter
from normadocs.pdf_generator import PDFGenerator

# Integration tests usually require real tools installed (Pandoc)
# We skip if pandoc is not found to avoid failing in environments without it.
PANDOC_AVAILABLE = shutil.which("pandoc") is not None


@unittest.skipUnless(PANDOC_AVAILABLE, "Pandoc not found")
class TestIntegration(unittest.TestCase):
    def setUp(self):
        self.test_dir = Path("tests/temp_integration")
        self.test_dir.mkdir(exist_ok=True)
        self.md_file = self.test_dir / "integration_test.md"
        self.md_file.write_text(
            """
**My Title**

Author Name
2023-01-01

# Introduction
This is a test paragraph.

# Methods
We used integration testing.
""",
            encoding="utf-8",
        )

    def tearDown(self):
        if self.test_dir.exists():
            shutil.rmtree(self.test_dir)

    def test_full_pipeline(self):
        """Test Markdown -> Preprocess -> Pandoc -> DOCX -> APA Styles -> PDF generation."""
        print("\\n  [Integration] Starting full pipeline test...")

        # 1. Preprocess
        processor = MarkdownPreprocessor()
        clean_md, meta = processor.process(self.md_file.read_text())

        self.assertEqual(meta.title, "My Title")
        self.assertEqual(meta.author, "Author Name")

        # 2. Pandoc
        output_docx = self.test_dir / "output.docx"
        runner = PandocRunner()
        success = runner.run(clean_md, str(output_docx))

        self.assertTrue(success, "Pandoc conversion failed")
        self.assertTrue(output_docx.exists())
        self.assertGreater(output_docx.stat().st_size, 0)

        # 3. APA Formatting
        # This requires python-docx to actually modify the file.
        # We verify it doesn't crash and modifies the file (size/mtime might change)
        try:
            formatter = APADocxFormatter(str(output_docx))
            formatter.process(meta)
            formatter.save(str(output_docx))
            print("  [Integration] APA Formatting applied successfully.")
        except Exception as e:
            self.fail(f"APA Formatting crashed: {e}")

        # 4. PDF Generation (Optional, mimics CLI behavior)
        # We try strict fallback if LibreOffice isn't there, or just skip if neither work.
        # But for test purposes, we want to ensure code runs.
        # We can't guarantee LibreOffice or WeasyPrint are installed in CI/dev env.
        # So we assert that IF they are present, it works.
        output_pdf = self.test_dir / "output.pdf"

        has_libreoffice = shutil.which("libreoffice") is not None
        has_weasyprint = importlib.util.find_spec("weasyprint") is not None

        if has_libreoffice:
            print("  [Integration] Testing LibreOffice PDF generation...")
            success_pdf = PDFGenerator.convert_with_libreoffice(
                str(output_docx), str(self.test_dir)
            )
            # LibreOffice might fail in headless CI if no display, so be lenient or check specific return
            # But if it returns True, file must exist
            if success_pdf:
                # The filename generated by libreoffice is based on input stem
                expected_pdf = self.test_dir / "output.pdf"
                self.assertTrue(
                    expected_pdf.exists(), "PDF file should exist after LibreOffice success"
                )

        elif has_weasyprint:
            print("  [Integration] Testing WeasyPrint PDF generation...")
            success_pdf = PDFGenerator.convert_with_weasyprint(clean_md, str(output_pdf))
            if success_pdf:
                self.assertTrue(
                    output_pdf.exists(), "PDF file should exist after WeasyPrint success"
                )
        else:
            print("  [Integration] Skipping PDF test (No LibreOffice/WeasyPrint found)")


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