"""Testing code generated by nbdev in unpackai/cv/data.py"""
# Generated automatically from notebook nbs/25_cv_data.ipynb

from unpackai.cv.data import *

# Test Cell
# For Test Cases (might have duplicate import because it will be in a dedicated file)
from pathlib import Path
from PIL import Image
from tempfile import TemporaryDirectory
from typing import List

import pytest

from test_common.utils_4_tests import DATA_DIR, IMG_DIR
from test_utils import GITHUB_TEST_DATA_URL, check_connection_github

# Test Cell
tiff_fname = "tif-multi-frame-with-tags.tif"
gif_fname = "animated.gif"
LOCAL_TEST_TIFF = IMG_DIR / "tiff" / tiff_fname
LOCAL_TEST_GIF = IMG_DIR / "tiff" / gif_fname

LOCAL_TEST_SUMMARY_TAGS = DATA_DIR / "tiff_summary_tags.txt"
LOCAL_TEST_REPR = DATA_DIR / "tiff_repr.txt"

GITHUB_TEST_IMG_DIR_URL = (
    "https://raw.githubusercontent.com/unpackAI/unpackai/main/test/img"
)
GITHUB_TEST_TIFF = f"{GITHUB_TEST_IMG_DIR_URL}/tiff/{tiff_fname}"
GITHUB_TEST_GIF = f"{GITHUB_TEST_IMG_DIR_URL}/tiff/{gif_fname}"


def test_exception_on_missing_path():
    with pytest.raises(FileExistsError) as msg:
        TiffImage("blabla.tif")
    expected_msg = f"Cannot find path {'blabla.tif'}"
    assert str(msg.value) == expected_msg


def test_exception_on_wrong_suffix():
    with pytest.raises(ValueError) as msg:
        TiffImage(IMG_DIR / "tiff" / gif_fname)
    expected_msg = f"Image file should be .tif or .tiff, not '{'.gif'}'"
    assert str(msg.value) == expected_msg


@pytest.fixture(scope="session")
def test_tiff_image():
    """Fixture to pass the test TIFF image path"""
    return LOCAL_TEST_TIFF


@pytest.fixture(scope="session")
def test_repr():
    return LOCAL_TEST_REPR.read_text()


@pytest.fixture(scope="session")
def test_summary_tag_printout():
    return LOCAL_TEST_SUMMARY_TAGS.read_text()


@pytest.fixture(scope="session")
def local_TiffImage(test_tiff_image):
    """Create instance of TiffImage by loading the test TIFF image"""
    return TiffImage(test_tiff_image)


class Test_TiffImage:
    """Testing class for TiffImage"""

    def test_n_frames(self, local_TiffImage):
        """Test property n_frame"""
        expected_value = 8
        assert local_TiffImage.n_frames == expected_value

    def test_size(self, local_TiffImage):
        """Test property Size"""
        expected_value = (512, 512)
        assert local_TiffImage.size == expected_value

    def test_tags(self, local_TiffImage):
        """Test returned dictionary"""
        expected_value_0 = {
            256: 512,
            257: 512,
            259: 1,
            262: 1,
            270: '{"shape": [512, 512]}',
            273: (320,),
            277: 1,
            278: 512,
            279: (32768,),
            282: 1.0,
            283: 1.0,
            296: 1,
            65001: "Specular reflection",
            305: "tifffile.py",
        }
        expected_value_1 = {
            256: 512,
            257: 512,
            259: 1,
            262: 1,
            270: '{"shape": [512, 512]}',
            273: (33408,),
            277: 1,
            278: 512,
            279: (32768,),
            282: 1.0,
            283: 1.0,
            296: 1,
            65001: "Attached gingiva",
            305: "tifffile.py",
        }
        local_TiffImage.tiff.seek(0)
        assert local_TiffImage.tags == expected_value_0
        local_TiffImage.tiff.seek(1)
        assert local_TiffImage.tags == expected_value_1

    def test_repr(self, local_TiffImage, capsys, test_repr):
        """Test the __repr__"""
        expected_value = test_repr
        local_TiffImage.tiff.seek(0)
        print(local_TiffImage)
        captured = capsys.readouterr()
        assert captured.out == expected_value

    def test_summary_tags_printout(
        self, local_TiffImage, capsys, test_summary_tag_printout
    ):
        """Test the tag summary method"""
        expected_value = test_summary_tag_printout
        local_TiffImage.tiff.seek(0)
        local_TiffImage.summary_tags()
        captured = capsys.readouterr()
        assert captured.out == expected_value

    def test_type_returned_by_get_frame(self, local_TiffImage):
        """Test that object is 'PIL.TiffImagePlugin.TiffImageFile'"""
        frame = local_TiffImage.get_frame(0)
        assert isinstance(frame, TiffImageFile)

    def test_extract_one_frame(self, local_TiffImage):
        """Test that frames are extracted and saved"""
        with TemporaryDirectory() as tdir:
            p2dir = Path(tdir)
            tiff.extract_one_frame(frame_nbr=2, dest=p2dir)
            assert (p2dir / "tif-multi-frame-with-tags-0002.jpg").is_file()
            tiff.extract_one_frame(frame_nbr=3, dest=p2dir, image_format="tif")
            assert (p2dir / "tif-multi-frame-with-tags-0003.tif").is_file()
            tiff.extract_one_frame(frame_nbr=4, dest=p2dir, fname="specific-name")
            assert (p2dir / "specific-name.jpg").is_file()

    def test_extract_frames_by_tag(self, local_TiffImage):
        """Test that all frames are saved and naming by tag is correct"""
        with TemporaryDirectory() as tdir:
            p2dir = Path(tdir)
            tiff.extract_frames(dest=p2dir, naming_method="tag_value", tag=65001)
            assert (p2dir / "tif-multi-frame-with-tags-Hair.tif").is_file()
            assert (p2dir / "tif-multi-frame-with-tags-Skin.tif").is_file()
            assert (p2dir / "tif-multi-frame-with-tags-Stain.tif").is_file()
            assert (p2dir / "tif-multi-frame-with-tags-Marginal_gingiva.tif").is_file()
            assert len(list(p2dir.iterdir())) == local_TiffImage.n_frames

    def test_extract_frames_by_nbr(self, local_TiffImage):
        """Test that all frames are saved and naming by number is correct"""
        with TemporaryDirectory() as tdir:
            p2dir = Path(tdir)
            tiff.extract_frames(dest=p2dir)
            assert (p2dir / "tif-multi-frame-with-tags-0001.tif").is_file()
            assert (p2dir / "tif-multi-frame-with-tags-0002.tif").is_file()
            assert (p2dir / "tif-multi-frame-with-tags-0005.tif").is_file()
            assert (p2dir / "tif-multi-frame-with-tags-0007.tif").is_file()
            assert len(list(p2dir.iterdir())) == local_TiffImage.n_frames

    def test_is_valid_frame_(self, local_TiffImage):
        nframes = local_TiffImage.n_frames
        assert local_TiffImage.is_valid_frame_(0)
        with pytest.raises(ValueError) as msg:
            local_TiffImage.is_valid_frame_(nframes + 1)
        expected_msg = (
            f"'frame_nbr' is {nframes+1} but this TIFF file only has {nframes} frames."
        )
        assert str(msg.value)[:-1] == expected_msg
