# SPDX-FileCopyrightText: 2022 James R. Barlow
# SPDX-License-Identifier: CC0-1.0

from __future__ import annotations

import pytest
from conftest import skip_if_pypy

import pikepdf
from pikepdf import (
    DataDecodingError,
    DeletedObjectError,
    Name,
    Pdf,
    PdfError,
    Stream,
    _core,
)


@pytest.fixture
def vera(resources):
    # A file that is not linearized
    with Pdf.open(resources / 'veraPDF test suite 6-2-10-t02-pass-a.pdf') as pdf:
        yield pdf


def test_foreign_linearization(vera):
    assert not vera.is_linearized
    with pytest.raises(RuntimeError, match="not linearized"):
        vera.check_linearization()


@pytest.mark.abi3_smoke
@pytest.mark.parametrize('msg, expected', [('QPDF', 'pikepdf.Pdf')])
def test_translate_qpdf_logic_error(msg, expected):
    assert _core._translate_qpdf_logic_error(msg) == expected


@pytest.mark.parametrize(
    'filter_,data,msg',
    [
        ('/ASCII85Decode', b'\xba\xad', 'character out of range'),
        ('/ASCII85Decode', b'fooz', 'unexpected z'),
        ('/ASCIIHexDecode', b'1g', 'character out of range'),
        ('/FlateDecode', b'\xba\xad', 'incorrect header check'),
    ],
)
@pytest.mark.abi3_smoke
def test_data_decoding_errors(filter_: str, data: bytes, msg: str):
    p = Pdf.new()
    st = Stream(p, data, Filter=Name(filter_))
    with pytest.raises(DataDecodingError, match=msg):
        st.read_bytes()


@pytest.mark.abi3_smoke
def test_system_error():
    with pytest.raises(FileNotFoundError):
        pikepdf._core._test.fopen_nonexistent_file()


@skip_if_pypy
def test_return_object_from_closed():
    p = Pdf.new()
    obj = p.Root.TestObject = p.make_stream(b'test stream')
    p.close()
    del p
    assert repr(obj) != ''
    with pytest.raises(DeletedObjectError):
        obj.read_bytes()


def test_object_type_assertion(resources):
    with pytest.raises(PdfError):
        with Pdf.open(resources / 'fuzz' / '378014596.pdf') as p:
            p.check_pdf_syntax()


def test_pdf_syntax_check_progress(resources):
    called = False

    def progress_fn(update):
        nonlocal called
        called = True

    with Pdf.open(resources / 'outlines.pdf') as p:
        p.check_pdf_syntax(progress_fn)

    assert called, "progress function not called"
