import os
import unittest
from unittest import skipUnless

import numpy as np
from numpy.testing import assert_array_equal
from parameterized import parameterized

from monai.apps.pathology.datasets import MaskedInferenceWSIDataset
from monai.apps.utils import download_url
from monai.utils import optional_import
from tests.utils import skip_if_quick

_, has_cim = optional_import("cucim")
_, has_osl = optional_import("openslide")

FILE_URL = "http://openslide.cs.cmu.edu/download/openslide-testdata/Generic-TIFF/CMU-1.tiff"
FILE_PATH = os.path.join(os.path.dirname(__file__), "testing_data", os.path.basename(FILE_URL))

MASK1 = os.path.join(os.path.dirname(__file__), "testing_data", "tissue_mask1.npy")
MASK2 = os.path.join(os.path.dirname(__file__), "testing_data", "tissue_mask2.npy")
MASK4 = os.path.join(os.path.dirname(__file__), "testing_data", "tissue_mask4.npy")

HEIGHT = 32914
WIDTH = 46000


def prepare_data():

    mask = np.zeros((WIDTH // 2, HEIGHT // 2))
    mask[100, 100] = 1
    np.save(MASK1, mask)
    mask[100, 100:102] = 1
    np.save(MASK2, mask)
    mask[100:102, 100:102] = 1
    np.save(MASK4, mask)


TEST_CASE_0 = [
    {
        "data": [
            {"image": FILE_PATH, "mask": MASK1},
        ],
        "patch_size": 1,
        "image_reader_name": "cuCIM",
    },
    [
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
    ],
]

TEST_CASE_1 = [
    {
        "data": [{"image": FILE_PATH, "mask": MASK2}],
        "patch_size": 1,
        "image_reader_name": "cuCIM",
    },
    [
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [101, 100],
        },
    ],
]

TEST_CASE_2 = [
    {
        "data": [{"image": FILE_PATH, "mask": MASK4}],
        "patch_size": 1,
        "image_reader_name": "cuCIM",
    },
    [
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 101],
        },
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [101, 100],
        },
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [101, 101],
        },
    ],
]

TEST_CASE_3 = [
    {
        "data": [
            {"image": FILE_PATH, "mask": MASK1},
        ],
        "patch_size": 2,
        "image_reader_name": "cuCIM",
    },
    [
        {
            "image": np.array(
                [
                    [[243, 243], [243, 243]],
                    [[243, 243], [243, 243]],
                    [[243, 243], [243, 243]],
                ],
                dtype=np.uint8,
            ),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
    ],
]

TEST_CASE_4 = [
    {
        "data": [
            {"image": FILE_PATH, "mask": MASK1},
            {"image": FILE_PATH, "mask": MASK2},
        ],
        "patch_size": 1,
        "image_reader_name": "cuCIM",
    },
    [
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [101, 100],
        },
    ],
]


TEST_CASE_OPENSLIDE_0 = [
    {
        "data": [
            {"image": FILE_PATH, "mask": MASK1},
        ],
        "patch_size": 1,
        "image_reader_name": "OpenSlide",
    },
    [
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
    ],
]

TEST_CASE_OPENSLIDE_1 = [
    {
        "data": [{"image": FILE_PATH, "mask": MASK2}],
        "patch_size": 1,
        "image_reader_name": "OpenSlide",
    },
    [
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [100, 100],
        },
        {
            "image": np.array([[[243]], [[243]], [[243]]], dtype=np.uint8),
            "name": "CMU-1",
            "mask_location": [101, 100],
        },
    ],
]


class TestMaskedInferenceWSIDataset(unittest.TestCase):
    def setUp(self):
        prepare_data()
        download_url(FILE_URL, FILE_PATH, "5a3cfd4fd725c50578ddb80b517b759f")

    @parameterized.expand(
        [
            TEST_CASE_0,
            TEST_CASE_1,
            TEST_CASE_2,
            TEST_CASE_3,
            TEST_CASE_4,
        ]
    )
    @skipUnless(has_cim, "Requires CuCIM")
    @skip_if_quick
    def test_read_patches_cucim(self, input_parameters, expected):
        dataset = MaskedInferenceWSIDataset(**input_parameters)
        self.compare_samples_expected(dataset, expected)

    @parameterized.expand(
        [
            TEST_CASE_OPENSLIDE_0,
            TEST_CASE_OPENSLIDE_1,
        ]
    )
    @skipUnless(has_osl, "Requires OpenSlide")
    @skip_if_quick
    def test_read_patches_openslide(self, input_parameters, expected):
        dataset = MaskedInferenceWSIDataset(**input_parameters)
        self.compare_samples_expected(dataset, expected)

    def compare_samples_expected(self, dataset, expected):
        for i in range(len(dataset)):
            self.assertTupleEqual(dataset[i][0]["image"].shape, expected[i]["image"].shape)
            self.assertIsNone(assert_array_equal(dataset[i][0]["image"], expected[i]["image"]))
            self.assertEqual(dataset[i][0]["name"], expected[i]["name"])
            self.assertListEqual(dataset[i][0]["mask_location"], expected[i]["mask_location"])


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

[((366, 390), 'monai.utils.optional_import', 'optional_import', (['"""cucim"""'], {}), "('cucim')\n", (381, 390), False, 'from monai.utils import optional_import\n'), ((404, 432), 'monai.utils.optional_import', 'optional_import', (['"""openslide"""'], {}), "('openslide')\n", (419, 432), False, 'from monai.utils import optional_import\n'), ((552, 577), 'os.path.dirname', 'os.path.dirname', (['__file__'], {}), '(__file__)\n', (567, 577), False, 'import os\n'), ((595, 621), 'os.path.basename', 'os.path.basename', (['FILE_URL'], {}), '(FILE_URL)\n', (611, 621), False, 'import os\n'), ((645, 670), 'os.path.dirname', 'os.path.dirname', (['__file__'], {}), '(__file__)\n', (660, 670), False, 'import os\n'), ((729, 754), 'os.path.dirname', 'os.path.dirname', (['__file__'], {}), '(__file__)\n', (744, 754), False, 'import os\n'), ((813, 838), 'os.path.dirname', 'os.path.dirname', (['__file__'], {}), '(__file__)\n', (828, 838), False, 'import os\n'), ((940, 975), 'numpy.zeros', 'np.zeros', (['(WIDTH // 2, HEIGHT // 2)'], {}), '((WIDTH // 2, HEIGHT // 2))\n', (948, 975), True, 'import numpy as np\n'), ((1003, 1023), 'numpy.save', 'np.save', (['MASK1', 'mask'], {}), '(MASK1, mask)\n', (1010, 1023), True, 'import numpy as np\n'), ((1055, 1075), 'numpy.save', 'np.save', (['MASK2', 'mask'], {}), '(MASK2, mask)\n', (1062, 1075), True, 'import numpy as np\n'), ((1111, 1131), 'numpy.save', 'np.save', (['MASK4', 'mask'], {}), '(MASK4, mask)\n', (1118, 1131), True, 'import numpy as np\n'), ((5145, 5236), 'parameterized.parameterized.expand', 'parameterized.expand', (['[TEST_CASE_0, TEST_CASE_1, TEST_CASE_2, TEST_CASE_3, TEST_CASE_4]'], {}), '([TEST_CASE_0, TEST_CASE_1, TEST_CASE_2, TEST_CASE_3,\n    TEST_CASE_4])\n', (5165, 5236), False, 'from parameterized import parameterized\n'), ((5323, 5360), 'unittest.skipUnless', 'skipUnless', (['has_cim', '"""Requires CuCIM"""'], {}), "(has_cim, 'Requires CuCIM')\n", (5333, 5360), False, 'from unittest import skipUnless\n'), ((5574, 5642), 'parameterized.parameterized.expand', 'parameterized.expand', (['[TEST_CASE_OPENSLIDE_0, TEST_CASE_OPENSLIDE_1]'], {}), '([TEST_CASE_OPENSLIDE_0, TEST_CASE_OPENSLIDE_1])\n', (5594, 5642), False, 'from parameterized import parameterized\n'), ((5697, 5738), 'unittest.skipUnless', 'skipUnless', (['has_osl', '"""Requires OpenSlide"""'], {}), "(has_osl, 'Requires OpenSlide')\n", (5707, 5738), False, 'from unittest import skipUnless\n'), ((6437, 6452), 'unittest.main', 'unittest.main', ([], {}), '()\n', (6450, 6452), False, 'import unittest\n'), ((5069, 5138), 'monai.apps.utils.download_url', 'download_url', (['FILE_URL', 'FILE_PATH', '"""5a3cfd4fd725c50578ddb80b517b759f"""'], {}), "(FILE_URL, FILE_PATH, '5a3cfd4fd725c50578ddb80b517b759f')\n", (5081, 5138), False, 'from monai.apps.utils import download_url\n'), ((5465, 5510), 'monai.apps.pathology.datasets.MaskedInferenceWSIDataset', 'MaskedInferenceWSIDataset', ([], {}), '(**input_parameters)\n', (5490, 5510), False, 'from monai.apps.pathology.datasets import MaskedInferenceWSIDataset\n'), ((5847, 5892), 'monai.apps.pathology.datasets.MaskedInferenceWSIDataset', 'MaskedInferenceWSIDataset', ([], {}), '(**input_parameters)\n', (5872, 5892), False, 'from monai.apps.pathology.datasets import MaskedInferenceWSIDataset\n'), ((1341, 1394), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (1349, 1394), True, 'import numpy as np\n'), ((1671, 1724), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (1679, 1724), True, 'import numpy as np\n'), ((1838, 1891), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (1846, 1891), True, 'import numpy as np\n'), ((2168, 2221), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (2176, 2221), True, 'import numpy as np\n'), ((2335, 2388), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (2343, 2388), True, 'import numpy as np\n'), ((2502, 2555), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (2510, 2555), True, 'import numpy as np\n'), ((2669, 2722), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (2677, 2722), True, 'import numpy as np\n'), ((3022, 3130), 'numpy.array', 'np.array', (['[[[243, 243], [243, 243]], [[243, 243], [243, 243]], [[243, 243], [243, 243]]]'], {'dtype': 'np.uint8'}), '([[[243, 243], [243, 243]], [[243, 243], [243, 243]], [[243, 243],\n    [243, 243]]], dtype=np.uint8)\n', (3030, 3130), True, 'import numpy as np\n'), ((3601, 3654), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (3609, 3654), True, 'import numpy as np\n'), ((3768, 3821), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (3776, 3821), True, 'import numpy as np\n'), ((3935, 3988), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (3943, 3988), True, 'import numpy as np\n'), ((4303, 4356), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (4311, 4356), True, 'import numpy as np\n'), ((4647, 4700), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (4655, 4700), True, 'import numpy as np\n'), ((4814, 4867), 'numpy.array', 'np.array', (['[[[243]], [[243]], [[243]]]'], {'dtype': 'np.uint8'}), '([[[243]], [[243]], [[243]]], dtype=np.uint8)\n', (4822, 4867), True, 'import numpy as np\n'), ((6170, 6234), 'numpy.testing.assert_array_equal', 'assert_array_equal', (["dataset[i][0]['image']", "expected[i]['image']"], {}), "(dataset[i][0]['image'], expected[i]['image'])\n", (6188, 6234), False, 'from numpy.testing import assert_array_equal\n')]