# ruff: noqa: SLF001
"""Tests for the Comic class using function-based pytest approach."""

import io
import tempfile
import zipfile
from pathlib import Path
from unittest.mock import Mock, patch

import pytest
from PIL import Image

from darkseid.comic import (
    COMIC_RACK_FILENAME,
    METRON_INFO_FILENAME,
    SUPPORTED_IMAGE_EXTENSIONS,
    Comic,
    ComicArchiveError,
    ComicError,
    ComicMetadataError,
    MetadataFormat,
)
from darkseid.metadata.data_classes import ImageMetadata, Metadata


# Fixtures
@pytest.fixture
def temp_dir():
    """Create a temporary directory for test files."""
    with tempfile.TemporaryDirectory() as tmpdir:
        yield Path(tmpdir)


@pytest.fixture
def sample_cbz_file(temp_dir):
    """Create a sample CBZ file for testing."""
    cbz_path = temp_dir / "test_comic.cbz"

    # Create a simple image in memory
    img = Image.new("RGB", (100, 150), color="red")
    img_bytes = io.BytesIO()
    img.save(img_bytes, format="JPEG")
    img_data = img_bytes.getvalue()

    # Create CBZ file
    with zipfile.ZipFile(cbz_path, "w") as zf:
        zf.writestr("page001.jpg", img_data)
        zf.writestr("page002.jpg", img_data)
        zf.writestr("ComicInfo.xml", "<ComicInfo><Title>Test Comic</Title></ComicInfo>")

    return cbz_path


@pytest.fixture
def sample_metadata():
    """Create sample metadata for testing."""
    metadata = Metadata()
    metadata.title = "Test Comic"
    metadata.issue = "1"
    metadata.page_count = 2
    return metadata


@pytest.fixture
def mock_archiver():
    """Create a mock archiver for testing."""
    archiver = Mock()
    archiver.is_write_operation_expected.return_value = True
    archiver.get_filename_list.return_value = ["page001.jpg", "page002.jpg", "ComicInfo.xml"]
    archiver.read_file.return_value = b"test image data"
    archiver.write_file.return_value = True
    archiver.remove_files.return_value = True
    return archiver


# Test MetadataFormat enum
def test_metadata_format_string_representation():
    """Test MetadataFormat string representation."""
    assert str(MetadataFormat.COMIC_INFO) == "ComicInfo"
    assert str(MetadataFormat.METRON_INFO) == "MetronInfo"
    assert str(MetadataFormat.UNKNOWN) == "Unknown"


# Test Comic initialization
def test_comic_init_with_valid_path(sample_cbz_file):
    """Test Comic initialization with valid path."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)
        assert comic.path == sample_cbz_file
        assert comic.name == sample_cbz_file.name


def test_comic_init_with_string_path(sample_cbz_file):
    """Test Comic initialization with string path."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(str(sample_cbz_file))
        assert comic.path == sample_cbz_file


def test_comic_init_nonexistent_file():
    """Test Comic initialization with nonexistent file."""
    with pytest.raises(ComicArchiveError, match="Comic file does not exist"):
        Comic("/nonexistent/path.cbz")


def test_comic_init_archiver_creation_failure(sample_cbz_file):
    """Test Comic initialization when archiver creation fails."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.side_effect = Exception("Archiver creation failed")
        with pytest.raises(ComicArchiveError, match="Failed to create archiver"):
            Comic(sample_cbz_file)


# Test string representations
def test_comic_str(sample_cbz_file):
    """Test Comic string representation."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)
        assert str(comic) == sample_cbz_file.name


def test_comic_repr(sample_cbz_file):
    """Test Comic detailed string representation."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        repr_str = repr(comic)
        assert "Comic(path=" in repr_str
        assert "pages=2" in repr_str


# Test properties
def test_comic_properties(sample_cbz_file):
    """Test Comic properties."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        assert comic.path == sample_cbz_file
        assert comic.name == sample_cbz_file.name
        assert comic.size > 0


# Test archive validation
def test_is_archive_valid_zip(sample_cbz_file):
    """Test archive validation for ZIP files."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic._archiver, "test", return_value=True):
            assert comic.is_archive_valid() is True


def test_is_archive_valid_rar(sample_cbz_file):
    """Test archive validation for RAR files."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic._archiver, "test", return_value=True):
            assert comic.is_archive_valid() is True


def test_is_archive_valid_neither(sample_cbz_file):
    """Test archive validation when neither ZIP nor RAR."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic._archiver, "test", return_value=False):
            assert comic.is_archive_valid() is False


def test_is_archive_valid_exception(sample_cbz_file):
    """Test archive validation when exception occurs."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic._archiver, "test", side_effect=Exception()):
            assert comic.is_archive_valid() is False


# Test archive type detection
# def test_zip_test(sample_cbz_file):
#     """Test ZIP file detection."""
#     with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
#         mock_factory.return_value = Mock()
#         comic = Comic(sample_cbz_file)
#         assert comic._archiver.test() is True
#
#
# def test_rar_test(sample_cbz_file):
#     """Test RAR file detection."""
#     with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
#         mock_factory.return_value = Mock()
#         comic = Comic(sample_cbz_file)
#
#         with patch("rarfile.is_rarfile", return_value=True):
#             assert comic._archiver.test() is True
#
#
# def test_rar_test_exception(sample_cbz_file):
#     """Test RAR file detection with exception."""
#     with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
#         mock_factory.return_value = Mock()
#         comic = Comic(sample_cbz_file)
#
#         with patch("rarfile.is_rarfile", side_effect=Exception()):
#             assert comic._archiver.test() is False


def test_is_zip_by_extension(temp_dir):
    """Test ZIP detection by file extension."""
    zip_path = temp_dir / "test.cbz"
    zip_path.touch()

    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(zip_path)
        assert comic.is_zip() is True


def test_is_rar_by_extension(temp_dir):
    """Test RAR detection by file extension."""
    rar_path = temp_dir / "test.cbr"
    rar_path.touch()

    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(rar_path)
        assert comic.is_rar() is True


# Test writability
def test_is_writable_true(sample_cbz_file):
    """Test writability when conditions are met."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.is_write_operation_expected.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch("os.access", return_value=True):
            assert comic.is_writable() is True


def test_is_writable_archiver_not_writable(sample_cbz_file):
    """Test writability when archiver doesn't support writing."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.is_write_operation_expected.return_value = False
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.is_writable() is False


def test_is_writable_no_file_access(sample_cbz_file):
    """Test writability when file access is denied."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.is_write_operation_expected.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch("os.access", return_value=False):
            assert comic.is_writable() is False


# Test comic archive detection
def test_seems_to_be_a_comic_archive(sample_cbz_file):
    """Test comic archive detection."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_zip", return_value=True):
            assert comic.seems_to_be_a_comic_archive() is True


def test_seems_to_be_a_comic_archive_no_pages(sample_cbz_file):
    """Test comic archive detection with no pages."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = []
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_zip", return_value=True):
            assert comic.seems_to_be_a_comic_archive() is False


# Test page operations
def test_get_page_valid_index(sample_cbz_file):
    """Test getting a page with valid index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_archiver.read_file.return_value = b"image data"
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        page_data = comic.get_page(0)
        assert page_data == b"image data"


def test_get_page_invalid_index(sample_cbz_file):
    """Test getting a page with invalid index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.get_page(-1) is None
        assert comic.get_page(10) is None


def test_get_page_read_error(sample_cbz_file):
    """Test getting a page when read fails."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_archiver.read_file.side_effect = OSError("Read failed")
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.get_page(0) is None


def test_get_page_name_valid_index(sample_cbz_file):
    """Test getting page name with valid index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.get_page_name(0) == "page1.jpg"
        assert comic.get_page_name(1) == "page2.jpg"


def test_get_page_name_invalid_index(sample_cbz_file):
    """Test getting page name with invalid index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.get_page_name(-1) is None
        assert comic.get_page_name(10) is None


# Test image detection
@pytest.mark.parametrize(
    ("filename", "expected"),
    [
        ("image.jpg", True),
        ("image.jpeg", True),
        ("image.png", True),
        ("image.gif", True),
        ("image.webp", True),
        ("image.JPG", True),  # Case insensitive
        ("image.txt", False),
        (".hidden.jpg", False),  # Hidden files
        ("normal.jpg", True),
    ],
)
def test_is_image(filename, expected):
    """Test image file detection."""
    path = Path(filename)
    assert Comic.is_image(path) == expected


# Test page list operations
def test_get_page_name_list(sample_cbz_file):
    """Test getting page name list."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = [
            "page2.jpg",
            "page1.jpg",
            "info.txt",
            ".hidden.jpg",
        ]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        page_list = comic.get_page_name_list()

        # Should be sorted and only include image files
        assert page_list == ["page1.jpg", "page2.jpg"]


def test_get_page_name_list_no_sort(sample_cbz_file):
    """Test getting page name list without sorting."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page2.jpg", "page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        page_list = comic.get_page_name_list(sort_list=False)

        # Should maintain original order but filter images
        assert page_list == ["page2.jpg", "page1.jpg"]


def test_get_page_name_list_cached(sample_cbz_file):
    """Test that page name list is cached."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # First call
        page_list1 = comic.get_page_name_list()
        # Second call should use cache
        page_list2 = comic.get_page_name_list()

        assert page_list1 == page_list2
        # Archiver should only be called once
        mock_archiver.get_filename_list.assert_called_once()


def test_get_page_name_list_exception(sample_cbz_file):
    """Test page name list when exception occurs."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.side_effect = Exception("Error")
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        page_list = comic.get_page_name_list()
        assert page_list == []


def test_get_number_of_pages(sample_cbz_file):
    """Test getting number of pages."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg", "info.txt"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.get_number_of_pages() == 2


def test_get_number_of_pages_cached(sample_cbz_file):
    """Test that page count is cached."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Multiple calls should use cache
        count1 = comic.get_number_of_pages()
        count2 = comic.get_number_of_pages()

        assert count1 == count2 == 1
        mock_archiver.get_filename_list.assert_called_once()


# Test metadata operations
def test_read_metadata_comic_rack(sample_cbz_file):
    """Test reading ComicInfo metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "ComicInfo.xml"]
        mock_archiver.read_file.return_value = b"<ComicInfo><Number>1</Number></ComicInfo>"
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch("darkseid.metadata.comicinfo.ComicInfo.metadata_from_string") as mock_parse:
            mock_metadata = Metadata()
            mock_metadata.issue = "1"
            mock_parse.return_value = mock_metadata

            metadata = comic.read_metadata(MetadataFormat.COMIC_INFO)
            assert metadata.issue == "1"


def test_read_metadata_metron_info(sample_cbz_file):
    """Test reading MetronInfo metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "MetronInfo.xml"]
        mock_archiver.read_file.return_value = b"<MetronInfo><Number>2</Number></MetronInfo>"
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch("darkseid.metadata.metroninfo.MetronInfo.metadata_from_string") as mock_parse:
            mock_metadata = Metadata()
            mock_metadata.issue = "2"
            mock_parse.return_value = mock_metadata

            metadata = comic.read_metadata(MetadataFormat.METRON_INFO)
            assert metadata.issue == "2"


def test_read_metadata_unknown_format(sample_cbz_file):
    """Test reading metadata with unknown format."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        metadata = comic.read_metadata(MetadataFormat.UNKNOWN)
        assert isinstance(metadata, Metadata)


def test_read_metadata_parse_error(sample_cbz_file):
    """Test reading metadata when parsing fails."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["ComicInfo.xml"]
        mock_archiver.read_file.return_value = b"invalid xml"
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch(
            "darkseid.metadata.comicinfo.ComicInfo.metadata_from_string", side_effect=Exception()
        ):
            metadata = comic.read_metadata(MetadataFormat.COMIC_INFO)
            assert isinstance(metadata, Metadata)


# Test raw metadata reading
# def test_read_raw_ci_metadata(sample_cbz_file):
#     """Test reading raw ComicInfo metadata."""
#     with patch('darkseid.comic.ArchiverFactory.create_archiver') as mock_factory:
#         mock_archiver = Mock()
#         mock_archiver.get_filename_list.return_value = ["ComicInfo.xml"]
#         mock_archiver.read_file.return_value = b"<ComicInfo>test</ComicInfo>"
#         mock_factory.return_value = mock_archiver
#
#         comic = Comic(sample_cbz_file)
#         raw_data = comic.read_raw_ci_metadata()
#         assert raw_data == "<ComicInfo>test</ComicInfo>"
#
#
# def test_read_raw_mi_metadata(sample_cbz_file):
#     """Test reading raw MetronInfo metadata."""
#     with patch('darkseid.comic.ArchiverFactory.create_archiver') as mock_factory:
#         mock_archiver = Mock()
#         mock_archiver.get_filename_list.return_value = ["MetronInfo.xml"]
#         mock_archiver.read_file.return_value = b"<MetronInfo>test</MetronInfo>"
#         mock_factory.return_value = mock_archiver
#
#         comic = Comic(sample_cbz_file)
#         raw_data = comic.read_raw_mi_metadata()
#         assert raw_data == "<MetronInfo>test</MetronInfo>"


def test_read_raw_metadata_not_found(sample_cbz_file):
    """Test reading raw metadata when file not found."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = []
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.read_raw_ci_metadata() is None


def test_read_raw_metadata_decode_error(sample_cbz_file):
    """Test reading raw metadata with decode error."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["ComicInfo.xml"]
        mock_archiver.read_file.side_effect = UnicodeDecodeError("utf-8", b"", 0, 1, "error")
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        assert comic.read_raw_ci_metadata() is None


# Test metadata writing
def test_write_metadata_comic_rack(sample_cbz_file, sample_metadata):
    """Test writing ComicInfo metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.is_write_operation_expected.return_value = True
        mock_archiver.write_file.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with (
            patch.object(comic, "is_writable", return_value=True),
            patch(
                "darkseid.metadata.comicinfo.ComicInfo.string_from_metadata", return_value="<xml/>"
            ),
        ):
            result = comic.write_metadata(sample_metadata, MetadataFormat.COMIC_INFO)
            assert result is True


def test_write_metadata_not_writable(sample_cbz_file, sample_metadata):
    """Test writing metadata when archive is not writable."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_writable", return_value=False):
            result = comic.write_metadata(sample_metadata, MetadataFormat.COMIC_INFO)
            assert result is False


def test_write_metadata_unsupported_format(sample_cbz_file, sample_metadata):
    """Test writing metadata with unsupported format."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with pytest.raises(ComicMetadataError, match="Unsupported metadata format"):
            comic.write_metadata(sample_metadata, MetadataFormat.UNKNOWN)


def test_write_metadata_none_metadata(sample_cbz_file):
    """Test writing None metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        result = comic.write_metadata(None, MetadataFormat.COMIC_INFO)  # type: ignore
        assert result is False


def test_write_metadata_exception(sample_cbz_file, sample_metadata):
    """Test writing metadata when exception occurs."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.is_write_operation_expected.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with (
            patch.object(comic, "is_writable", return_value=True),
            patch.object(comic, "_apply_archive_info_to_metadata", side_effect=Exception()),
        ):
            result = comic.write_metadata(sample_metadata, MetadataFormat.COMIC_INFO)
            assert result is False


# Test metadata removal
def test_remove_metadata_comic_rack(sample_cbz_file):
    """Test removing ComicInfo metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["ComicInfo.xml", "page1.jpg"]
        mock_archiver.remove_files.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "has_metadata", return_value=True):
            result = comic.remove_metadata(MetadataFormat.COMIC_INFO)
            assert result is True


def test_remove_metadata_not_found(sample_cbz_file):
    """Test removing metadata when not found."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "has_metadata", return_value=False):
            result = comic.remove_metadata(MetadataFormat.COMIC_INFO)
            assert result is True  # No metadata to remove is considered success


def test_remove_metadata_unsupported_format(sample_cbz_file):
    """Test removing metadata with unsupported format."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        result = comic.remove_metadata(MetadataFormat.UNKNOWN)
        assert result is False


def test_remove_metadata_case_insensitive(sample_cbz_file):
    """Test removing metadata with case-insensitive filename matching."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["COMICINFO.XML", "page1.jpg"]
        mock_archiver.remove_files.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "has_metadata", return_value=True):
            result = comic.remove_metadata(MetadataFormat.COMIC_INFO)
            assert result is True
            mock_archiver.remove_files.assert_called_once_with(["COMICINFO.XML"])


def test_remove_metadata_exception(sample_cbz_file):
    """Test removing metadata when exception occurs."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.side_effect = Exception("Error")
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "has_metadata", return_value=True):
            result = comic.remove_metadata(MetadataFormat.COMIC_INFO)
            assert result is False


# Test page removal
def test_remove_pages_success(sample_cbz_file):
    """Test successful page removal."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg", "page3.jpg"]
        mock_archiver.remove_files.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_writable", return_value=True):
            result = comic.remove_pages([0, 2])  # Remove first and third pages
            assert result is True
            mock_archiver.remove_files.assert_called_once_with(["page1.jpg", "page3.jpg"])


def test_remove_pages_empty_list(sample_cbz_file):
    """Test removing pages with empty list."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        result = comic.remove_pages([])
        assert result is False


def test_remove_pages_not_writable(sample_cbz_file):
    """Test removing pages when archive is not writable."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_writable", return_value=False):
            result = comic.remove_pages([0])
            assert result is False


def test_remove_pages_invalid_index(sample_cbz_file):
    """Test removing pages with invalid index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_writable", return_value=True):
            result = comic.remove_pages([10])  # Invalid index
            assert result is False


def test_remove_pages_exception(sample_cbz_file):
    """Test removing pages when exception occurs."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_archiver.remove_files.side_effect = Exception("Error")
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_writable", return_value=True):
            result = comic.remove_pages([0])
            assert result is False


# Test metadata detection
def test_has_metadata_comic_rack(sample_cbz_file):
    """Test ComicInfo metadata detection."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "ComicInfo.xml"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "seems_to_be_a_comic_archive", return_value=True):
            assert comic.has_metadata(MetadataFormat.COMIC_INFO) is True


def test_has_metadata_metron_info(sample_cbz_file):
    """Test MetronInfo metadata detection."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "MetronInfo.xml"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "seems_to_be_a_comic_archive", return_value=True):
            assert comic.has_metadata(MetadataFormat.METRON_INFO) is True


def test_has_metadata_not_comic_archive(sample_cbz_file):
    """Test metadata detection when not a comic archive."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "seems_to_be_a_comic_archive", return_value=False):
            assert comic.has_metadata(MetadataFormat.COMIC_INFO) is False


def test_has_metadata_case_insensitive(sample_cbz_file):
    """Test metadata detection is case insensitive."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "COMICINFO.XML"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "seems_to_be_a_comic_archive", return_value=True):
            assert comic.has_metadata(MetadataFormat.COMIC_INFO) is True


def test_has_metadata_cached(sample_cbz_file):
    """Test that metadata detection is cached."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["ComicInfo.xml"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "seems_to_be_a_comic_archive", return_value=True):
            # Multiple calls should use cache
            result1 = comic.has_metadata(MetadataFormat.COMIC_INFO)
            result2 = comic.has_metadata(MetadataFormat.COMIC_INFO)

            assert result1 == result2 is True
            mock_archiver.get_filename_list.assert_called_once()


def test_has_metadata_exception(sample_cbz_file):
    """Test metadata detection when exception occurs."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.side_effect = Exception("Error")
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with patch.object(comic, "seems_to_be_a_comic_archive", return_value=True):
            assert comic.has_metadata(MetadataFormat.COMIC_INFO) is False


def test_has_metadata_unknown_format(sample_cbz_file):
    """Test metadata detection with unknown format."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        assert comic.has_metadata(MetadataFormat.UNKNOWN) is False


# Test archive info application to metadata
def test_apply_archive_info_to_metadata_basic(sample_cbz_file, sample_metadata):
    """Test applying basic archive info to metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)
        comic._apply_archive_info_to_metadata(sample_metadata)

        assert sample_metadata.page_count == 2


def test_apply_archive_info_to_metadata_with_page_sizes(sample_cbz_file, sample_metadata):
    """Test applying archive info with page size calculation."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_archiver.read_file.return_value = b"fake image data"
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Add a page that needs size calculation
        page = ImageMetadata()
        page["Image"] = "0"
        sample_metadata.pages = [page]

        # Mock PIL Image
        mock_image = Mock()
        mock_image.size = (100, 150)
        mock_image.__enter__ = Mock(return_value=mock_image)
        mock_image.__exit__ = Mock(return_value=None)

        with patch("PIL.Image.open", return_value=mock_image):
            comic._apply_archive_info_to_metadata(sample_metadata, calc_page_sizes=True)

        assert page["ImageSize"] == "15"  # len(b"fake image data")
        assert page["ImageWidth"] == "100"
        assert page["ImageHeight"] == "150"


def test_apply_archive_info_to_metadata_skip_complete_pages(sample_cbz_file, sample_metadata):
    """Test skipping pages that already have complete info."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Add a page with complete info
        page = ImageMetadata()
        page["Image"] = "0"
        page["ImageSize"] = "1000"
        page["ImageWidth"] = "100"
        page["ImageHeight"] = "150"
        sample_metadata.pages = [page]

        comic._apply_archive_info_to_metadata(sample_metadata, calc_page_sizes=True)

        # Page info should remain unchanged
        assert page["ImageSize"] == "1000"
        mock_archiver.read_file.assert_not_called()


def test_apply_archive_info_to_metadata_invalid_page_index(sample_cbz_file, sample_metadata):
    """Test handling invalid page index during info application."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Add a page with invalid index
        page = ImageMetadata()
        page["Image"] = "invalid"
        sample_metadata.pages = [page]

        # Should not raise exception
        comic._apply_archive_info_to_metadata(sample_metadata, calc_page_sizes=True)


def test_apply_archive_info_to_metadata_image_error(sample_cbz_file, sample_metadata):
    """Test handling image processing errors during info application."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_archiver.read_file.return_value = b"fake image data"
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        page = ImageMetadata()
        page["Image"] = "0"
        sample_metadata.pages = [page]

        with patch("PIL.Image.open", side_effect=OSError("Cannot identify image")):
            # Should not raise exception
            comic._apply_archive_info_to_metadata(sample_metadata, calc_page_sizes=True)

            # Should still set image size
            assert page["ImageSize"] == "15"


# Test ZIP export
def test_export_as_zip_already_zip(sample_cbz_file, temp_dir):
    """Test exporting when already ZIP format."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_zip", return_value=True):
            result = comic.export_as_zip(temp_dir / "output.cbz")
            assert result is True


# def test_export_as_zip_success(sample_cbz_file, temp_dir):
#     """Test successful ZIP export."""
#     with patch('darkseid.comic.ArchiverFactory.create_archiver') as mock_factory:
#         mock_archiver = Mock()
#         mock_factory.return_value = mock_archiver
#
#         comic = Comic(sample_cbz_file)
#
#         with patch.object(comic, 'is_zip', return_value=False):
#             with patch('darkseid.archivers.zip.ZipArchiver') as mock_zip_class:
#                 mock_zip_archiver = Mock()
#                 mock_zip_archiver.copy_from_archive.return_value = True
#                 mock_zip_class.return_value = mock_zip_archiver
#
#                 result = comic.export_as_zip(temp_dir / "output.cbz")
#                 assert result is True


def test_export_as_zip_failure(sample_cbz_file, temp_dir):
    """Test ZIP export failure."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with (
            patch.object(comic, "is_zip", return_value=False),
            patch("darkseid.archivers.zip.ZipArchiver", side_effect=Exception("Error")),
        ):
            result = comic.export_as_zip(temp_dir / "output.cbz")
            assert result is False


# Test metadata formats detection
def test_get_metadata_formats(sample_cbz_file):
    """Test getting available metadata formats."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "has_metadata") as mock_has:

            def has_metadata_side_effect(fmt):
                return fmt in [MetadataFormat.COMIC_INFO, MetadataFormat.METRON_INFO]

            mock_has.side_effect = has_metadata_side_effect

            formats = comic.get_metadata_formats()
            expected = {MetadataFormat.COMIC_INFO, MetadataFormat.METRON_INFO}
            assert formats == expected


def test_get_metadata_formats_empty(sample_cbz_file):
    """Test getting metadata formats when none present."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "has_metadata", return_value=False):
            formats = comic.get_metadata_formats()
            assert formats == set()


# Test comic validation
def test_is_valid_comic_true(sample_cbz_file):
    """Test valid comic detection."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with (
            patch.object(comic, "is_archive_valid", return_value=True),
            patch.object(comic, "seems_to_be_a_comic_archive", return_value=True),
        ):
            assert comic.is_valid_comic() is True


def test_is_valid_comic_file_not_exists():
    """Test comic validation when file doesn't exist."""
    # This will fail during initialization, so we test differently
    non_existent = Path("/nonexistent/file.cbz")

    with pytest.raises(ComicArchiveError):
        Comic(non_existent)


def test_is_valid_comic_invalid_archive(sample_cbz_file):
    """Test comic validation with invalid archive."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_archive_valid", return_value=False):
            assert comic.is_valid_comic() is False


def test_is_valid_comic_not_comic_archive(sample_cbz_file):
    """Test comic validation when not a comic archive."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with (
            patch.object(comic, "is_archive_valid", return_value=True),
            patch.object(comic, "seems_to_be_a_comic_archive", return_value=False),
        ):
            assert comic.is_valid_comic() is False


def test_is_valid_comic_exception(sample_cbz_file):
    """Test comic validation when exception occurs."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with patch.object(comic, "is_archive_valid", side_effect=Exception("Error")):
            assert comic.is_valid_comic() is False


# Test cache reset
def test_reset_cache(sample_cbz_file):
    """Test cache reset functionality."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Populate cache
        comic.get_number_of_pages()
        assert comic._page_count is not None

        # Reset cache
        comic._reset_cache()

        # Verify cache is cleared
        assert comic._page_count is None
        assert comic._page_list is None
        assert comic._has_ci is None
        assert comic._has_mi is None
        assert comic._metadata is None


# Test page validation
def test_validate_page_index_valid(sample_cbz_file):
    """Test page index validation with valid index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Should not raise exception
        comic._validate_page_index(0)
        comic._validate_page_index(1)


def test_validate_page_index_negative(sample_cbz_file):
    """Test page index validation with negative index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        with pytest.raises(ValueError, match="Page index cannot be negative"):
            comic._validate_page_index(-1)


def test_validate_page_index_out_of_range(sample_cbz_file):
    """Test page index validation with out of range index."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with pytest.raises(ValueError, match="Page index .* is out of range"):
            comic._validate_page_index(10)


# Test page list validation and fixing
def test_validate_and_fix_page_list_mismatch(sample_cbz_file):
    """Test page list validation when counts mismatch."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Create metadata with wrong page count
        comic._metadata = Metadata()
        comic._metadata.pages = [ImageMetadata()]  # Only 1 page in metadata

        comic._validate_and_fix_page_list()

        # Pages should be reset and default list created
        assert len(comic._metadata.pages) == 2  # Should match actual page count


def test_validate_and_fix_page_list_empty_pages(sample_cbz_file):
    """Test page list validation when pages list is empty."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "page2.jpg"]
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Create metadata with empty pages
        comic._metadata = Metadata()
        comic._metadata.pages = []

        with patch.object(comic._metadata, "set_default_page_list") as mock_set_default:
            comic._validate_and_fix_page_list()
            mock_set_default.assert_called_once_with(2)


def test_validate_and_fix_page_list_none_metadata(sample_cbz_file):
    """Test page list validation when metadata is None."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_factory.return_value = Mock()
        comic = Comic(sample_cbz_file)

        comic._metadata = None

        # Should not raise exception
        comic._validate_and_fix_page_list()


# Test error handling in exception classes
def test_comic_error_inheritance():
    """Test that custom exceptions inherit correctly."""
    assert issubclass(ComicArchiveError, ComicError)
    assert issubclass(ComicMetadataError, ComicError)
    assert issubclass(ComicError, Exception)


def test_comic_exceptions_can_be_raised():
    """Test that custom exceptions can be raised and caught."""
    msg = "Test error"
    with pytest.raises(ComicError):
        raise ComicError(msg)

    msg = "Archive error"
    with pytest.raises(ComicArchiveError):
        raise ComicArchiveError(msg)

    msg = "Metadata error"
    with pytest.raises(ComicMetadataError):
        raise ComicMetadataError(msg)


# Test constants
def test_constants():
    """Test that constants are properly defined."""
    assert isinstance(SUPPORTED_IMAGE_EXTENSIONS, frozenset)
    assert ".jpg" in SUPPORTED_IMAGE_EXTENSIONS
    assert ".jpeg" in SUPPORTED_IMAGE_EXTENSIONS
    assert ".png" in SUPPORTED_IMAGE_EXTENSIONS
    assert ".gif" in SUPPORTED_IMAGE_EXTENSIONS
    assert ".webp" in SUPPORTED_IMAGE_EXTENSIONS

    assert COMIC_RACK_FILENAME == "ComicInfo.xml"
    assert METRON_INFO_FILENAME == "MetronInfo.xml"


# Integration-style tests
def test_full_workflow_read_metadata(sample_cbz_file):
    """Test a complete workflow of reading metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.get_filename_list.return_value = ["page1.jpg", "ComicInfo.xml"]
        mock_archiver.read_file.return_value = b"<ComicInfo><Number>1.MU</Number></ComicInfo>"
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        # Check if has metadata
        with patch.object(comic, "seems_to_be_a_comic_archive", return_value=True):
            assert comic.has_metadata(MetadataFormat.COMIC_INFO) is True

        # Read raw metadata
        raw_data = comic.read_raw_ci_metadata()
        assert raw_data == "<ComicInfo><Number>1.MU</Number></ComicInfo>"

        # Read parsed metadata
        with patch("darkseid.metadata.comicinfo.ComicInfo.metadata_from_string") as mock_parse:
            mock_metadata = Metadata()
            mock_metadata.issue = "1.MU"
            mock_parse.return_value = mock_metadata

            metadata = comic.read_metadata(MetadataFormat.COMIC_INFO)
            assert metadata.issue == "1.MU"


def test_full_workflow_write_and_remove_metadata(sample_cbz_file, sample_metadata):
    """Test a complete workflow of writing and removing metadata."""
    with patch("darkseid.comic.ArchiverFactory.create_archiver") as mock_factory:
        mock_archiver = Mock()
        mock_archiver.is_write_operation_expected.return_value = True
        mock_archiver.get_filename_list.return_value = ["page1.jpg"]
        mock_archiver.write_file.return_value = True
        mock_archiver.remove_files.return_value = True
        mock_factory.return_value = mock_archiver

        comic = Comic(sample_cbz_file)

        with (
            patch.object(comic, "is_writable", return_value=True),
            patch(
                "darkseid.metadata.comicinfo.ComicInfo.string_from_metadata", return_value="<xml/>"
            ),
        ):
            # Write metadata
            result = comic.write_metadata(sample_metadata, MetadataFormat.COMIC_INFO)
            assert result is True

            # Now remove it
            with patch.object(comic, "has_metadata", return_value=True):
                result = comic.remove_metadata(MetadataFormat.COMIC_INFO)
                assert result is True
