"""Tests for the Parser ABC and its implementations."""

from pathlib import Path

import pytest
from docling_core.types.doc.document import DoclingDocument

from quber.core.parsers import (
    DoclingParser,
    LegacyDoclingParser,
    MockParser,
    Parser,
    ParseResult,
    TunedFinancialParser,
    parser_for_preset,
)


def test_parser_protocol_isinstance_with_mock():
    mp = MockParser()
    assert isinstance(mp, Parser)


def test_parser_protocol_isinstance_with_docling():
    dp = TunedFinancialParser()
    assert isinstance(dp, Parser)
    assert isinstance(dp, DoclingParser)


def test_docling_parser_is_abstract():
    with pytest.raises(TypeError):
        DoclingParser()  # type: ignore[abstract]


def test_mock_parser_returns_parse_result():
    mp = MockParser()
    result = mp.parse(Path("nonexistent.pdf"))
    assert isinstance(result, ParseResult)
    assert isinstance(result.document, DoclingDocument)


def test_mock_parser_returns_injected_result():
    custom = ParseResult(document=DoclingDocument(name="custom"))
    mp = MockParser(result=custom)
    assert mp.parse(Path("x.pdf")) is custom


def test_tuned_financial_parser_init_defaults():
    dp = TunedFinancialParser()
    assert dp.do_ocr is False
    assert dp.do_table_structure is True
    assert dp.do_cell_matching is True
    assert dp.preset == "tuned-financial"


def test_legacy_parser_preset():
    dp = LegacyDoclingParser()
    assert dp.preset == "legacy"
    assert dp.backend_label == "default"


def test_parser_for_preset_maps_to_classes():
    assert isinstance(parser_for_preset("tuned-financial"), TunedFinancialParser)
    assert isinstance(parser_for_preset("legacy"), LegacyDoclingParser)


def test_parser_for_preset_rejects_unknown():
    with pytest.raises(ValueError, match="Unknown parser preset"):
        parser_for_preset("bogus")


def test_preset_pipeline_options_differ():
    """The two presets must produce the configurations they did pre-refactor."""
    legacy_opts = LegacyDoclingParser().build_pipeline_options()
    tuned_opts = TunedFinancialParser().build_pipeline_options()

    # legacy: bare options, OCR off by default, no picture classification
    assert legacy_opts.do_ocr is False
    assert legacy_opts.do_picture_classification is False

    # tuned: OCR forced on, picture classification + images on, ACCURATE mode
    assert tuned_opts.do_ocr is True
    assert tuned_opts.do_picture_classification is True
    assert tuned_opts.generate_picture_images is True
    assert tuned_opts.table_structure_options.mode.name == "ACCURATE"  # type: ignore[union-attr]
