""" 
This script runs all readers on dummy data files generated by the other scripts
in this folder, to ensure that they can read the files without errors.
"""
# %% IMPORTS
# this file lays in project/Z_private and I want to import from project/omio:
import re
import sys, os
from typing import Union
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'omio')))
import omio as om
# %% HELLO WORLD TEST
om.hello_world()
# %% DEFINE RELATIVE PATHS TO DUMMY DATA
""" 
Please, set in the following variable example_data_path the absolute or
relative path to the folder where the dummy data files are stored. For example
if you place example_data one folder up from this script, you can set:

example_data_path = "../example_data"

"""

#example_data_path = "../example_data" # when executing this script in VS Code's interactive window
example_data_path = "./example_data" # when executing this script directly in a terminal from within the main repo folder

# the following paths should not be changed:
PATH_TO_TIF_XY          = os.path.join(example_data_path, "tif_dummy_data/tif/YX.tif")
PATH_TO_TIF_TYX_T1      = os.path.join(example_data_path, "tif_dummy_data/tif/TYX_T1.tif")
PATH_TO_TIF_ZTYX_Z1_T1  = os.path.join(example_data_path, "tif_dummy_data/tif/ZTYX_Z1_T1.tif")
PATH_TO_TIF_CZTYX_C1_Z1_T1 = os.path.join(example_data_path, "tif_dummy_data/tif/CZTYX_C1_Z1_T1.tif")
PATH_TO_TIF_CZTYX_C2_Z1_T1 = os.path.join(example_data_path, "tif_dummy_data/tif/CZTYX_C2_Z1_T1.tif")
PATH_TO_TIF_CZTYX_C2_Z10_T1 = os.path.join(example_data_path, "tif_dummy_data/tif/CZTYX_C2_Z10_T1.tif")
PATH_TO_TIF_TZCYX_T5_Z10_C2 = os.path.join(example_data_path, "tif_dummy_data/tif/TZCYX_T5_Z10_C2.tif")

PATH_TO_OME_TIF         = os.path.join(example_data_path, "tif_dummy_data/ome_tif/TZCYX_T5_Z10_C2.ome.tif")
PATH_TO_PAGINATED_TIF   = os.path.join(example_data_path, "tif_dummy_data/paginated_tif/paginated.ome.tif")
PATH_TO_MULTISERIES_TIF1= os.path.join(example_data_path, "tif_dummy_data/multiseries_tif/multiseries_rgb_with_equal_shapes.tif")
PATH_TO_MULTISERIES_TIF2= os.path.join(example_data_path, "tif_dummy_data/multiseries_tif/multiseries_rgb_with_unequal_series.tif")
PATH_TO_MULTISERIES_TIF3= os.path.join(example_data_path, "tif_dummy_data/multiseries_tif/multiseries_minisblack.tif")
PATH_TO_MULTISERIES_TIF4= os.path.join(example_data_path, "tif_dummy_data/multiseries_tif/multiseries_rgb_minisblack_mixture.tif")

PATH_TO_MULTIPLE_TIFS_FOLDER = os.path.join(example_data_path, "tif_dummy_data/tif_folder_with_multiple_files/")

PATH_TO_CZI_FILE        = os.path.join(example_data_path, "czi_test_file/xt-scan-lsm980.czi")

PATH_TO_RAW_FILE_1      = os.path.join(example_data_path, "thorlabs_dummy_data/case_C1_Z1_T1/example_C1_Z1_T1.raw")
PATH_TO_RAW_FILE_2      = os.path.join(example_data_path, "thorlabs_dummy_data/case_C2_Z1_T1/example_C2_Z1_T1.raw")
PATH_TO_RAW_FILE_3      = os.path.join(example_data_path, "thorlabs_dummy_data/case_C2_Z10_T5/example_C2_Z10_T5.raw")  

PATHS_TO_ALL_SINGLE_FILES = [PATH_TO_TIF_XY,
                             PATH_TO_TIF_TYX_T1,
                             PATH_TO_TIF_ZTYX_Z1_T1,
                             PATH_TO_TIF_CZTYX_C1_Z1_T1,
                             PATH_TO_TIF_CZTYX_C2_Z1_T1,
                             PATH_TO_TIF_CZTYX_C2_Z10_T1,
                             PATH_TO_TIF_TZCYX_T5_Z10_C2,
                             PATH_TO_OME_TIF,
                             PATH_TO_PAGINATED_TIF,
                             PATH_TO_MULTISERIES_TIF1,
                             PATH_TO_MULTISERIES_TIF2,
                             PATH_TO_MULTISERIES_TIF3,
                             PATH_TO_MULTISERIES_TIF4,
                             PATH_TO_CZI_FILE,
                             PATH_TO_RAW_FILE_1,
                             PATH_TO_RAW_FILE_2,
                             PATH_TO_RAW_FILE_3]


PATH_TO_TAGGED_FOLDER_1  = os.path.join(example_data_path, "tif_folder_stacks/FOV1_time001/")
PATH_TO_TAGGED_FOLDER_2  = os.path.join(example_data_path, "tif_folder_stacks/HC_day1_with_additional_file/")

TAGGED_FOLDER_PATHS = [PATH_TO_TAGGED_FOLDER_1, PATH_TO_TAGGED_FOLDER_2]

PATH_TO_BIDS_PROJECT_FOLDER  = os.path.join(example_data_path, "BIDS project example")

# create error report collector
error_report_collector = {}
# %% TEST IMCONVERT FOR ALL SINGLE FILES

# print pwd:
print(f"Current working directory: {os.getcwd()}")

# conversion runs using NumPy arrays as intermediate format (default):
print("\n\nNow testing conversion with default zarr_store=None (NumPy arrays):\n")
for file_path in PATHS_TO_ALL_SINGLE_FILES:
    # file_path = PATH_TO_TIF_XY
    print(f"\n--- Testing om.imread() on file: {file_path} ---")
    try:
        img = om.imconvert(file_path, 
                                    relative_path="../omio_test_single_file_conversion" if not "czi" in file_path else "omio_test_single_file_conversion",
                                    overwrite=True)
    except Exception as e:
        file_name = re.split(r'[\\/]', file_path)[-1]
        error_report_collector[file_name] = {"filepath": file_path, "Test": "conversion (NumPy)","error": str(e)}
        print(f"Error reading file {file_path}: {e}")
        

# conversion runs using Zarr for storing the images into memory:
print("\n\nNow testing conversion with zarr_store='memory':\n")
for file_path in PATHS_TO_ALL_SINGLE_FILES:
    print(f"\n--- Testing om.imread() on file: {file_path} ---")
    try:
        img = om.imconvert(file_path, 
                                    relative_path="../omio_test_single_file_conversion" if not "czi" in file_path else "omio_test_single_file_conversion",
                                    overwrite=True, zarr_store="memory")
    except Exception as e:
        file_name = re.split(r'[\\/]', file_path)[-1]
        error_report_collector[file_name] = {"filepath": file_path, "Test": "conversion (Zarr in memory)","error": str(e)}
        print(f"Error reading file {file_path}: {e}")
        
# conversion runs using Zarr for intermediate storing the images onto disk (memory mapping):
print("\n\nNow testing conversion with zarr_store='disk' (memory-mapping):\n")
for file_path in PATHS_TO_ALL_SINGLE_FILES:
    print(f"\n--- Testing om.imread() on file: {file_path} ---")
    try:
        img = om.imconvert(file_path, 
                                    relative_path="../omio_test_single_file_conversion" if not "czi" in file_path else "omio_test_single_file_conversion",
                                    overwrite=True, zarr_store="disk")
    except Exception as e:
        file_name = re.split(r'[\\/]', file_path)[-1]
        error_report_collector[file_name] = {"filepath": file_path, "Test": "conversion (Zarr on disk)","error": str(e)}
        print(f"Error reading file {file_path}: {e}")

# %% TEST IMCONVERT FOR FOLDER CONTAINING MULTIPLE TIF FILES
om.imconvert(PATH_TO_MULTIPLE_TIFS_FOLDER, relative_path="omio_converted_multiple_tifs_folder",
             overwrite=True)

om.imconvert(PATH_TO_MULTIPLE_TIFS_FOLDER, relative_path="omio_converted_multiple_tifs_folder_merged",
             overwrite=True, merge_multiple_files_in_folder=True, merge_along_axis="T", zeropadding=True)

om.imconvert(PATH_TO_MULTIPLE_TIFS_FOLDER, relative_path="omio_converted_multiple_tifs_folder_merged",
             overwrite=True, merge_multiple_files_in_folder=True, merge_along_axis="T", zeropadding=False)
# %% TEST IMCONVERT FOR TAGGED FOLDER-STACKS
""" 
here, we test reading of folder-stacks where each sub-stack is stored as a separate file 
in a folder (e.g., time-lapse series where each time-point is a separate file/stack in a folder).
We use the tif dummy data files generated with generate_tif_dummy_files.py script.

PATH_TO_TAGGED_FOLDER_1 and PATH_TO_TAGGED_FOLDER_2 are paths to folders, that start with a specific
tag (here FOV1_ and HC_ respectively). imconvert get this path and extracts automatically the tag
to group the files accordingly.
"""

for folder_path in TAGGED_FOLDER_PATHS:
    # folder_path = PATH_TO_TAGGED_FOLDER_1
    print(f"\n--- Testing om.imread() on tagged folder-stack: {folder_path} ---")
    try:
        curr_tag = os.path.basename(folder_path).split("_")[0]  # just to get the folder name for the error report
        img = om.imconvert(folder_path, 
                           relative_path=f"../omio_converted_folderstacks_{curr_tag}",
                           folder_stacks=True)
        img = om.imconvert(folder_path, 
                           relative_path=f"../omio_converted_folderstacks_{curr_tag}_merged_wo_zeropadding",
                           zeropadding=False,
                           folder_stacks=True,
                           merge_folder_stacks=True,
                           merge_along_axis="T",
                           overwrite=True)
        img = om.imconvert(folder_path, 
                           relative_path=f"../omio_converted_folderstacks_{curr_tag}_merged_w_zeropadding",
                           zeropadding=True,
                           folder_stacks=True,
                           merge_folder_stacks=True,
                           merge_along_axis="T",
                           overwrite=True)
    except Exception as e:
        folder_name = re.split(r'[\\/]', folder_path)[-1]
        error_report_collector[folder_name] = {"filepath": folder_path, "Test": "tagged folder-stack conversion","error": str(e)}
        print(f"Error reading tagged folder-stack {folder_path}: {e}")

# %% BIDS BATCH CONVERSION TEST

# TP001 is present in all subjects and contains a single tif in each exp folder:
om.bids_batch_convert(fname=PATH_TO_BIDS_PROJECT_FOLDER, sub="ID", exp="TP001",
    exp_match_mode="startswith", relative_path="omio_outputs", zarr_store=None)

# TP0002 is only present in one subject only and contains a single tif in its exp folder:
om.bids_batch_convert(fname=PATH_TO_BIDS_PROJECT_FOLDER, sub="ID", exp="TP002",
    exp_match_mode="startswith", relative_path="omio_outputs", zarr_store=None)

# TP003 is present in all subjects and contains a single raw file in each exp folder:
om.bids_batch_convert(fname=PATH_TO_BIDS_PROJECT_FOLDER, sub="ID", exp="TP003",
    exp_match_mode="startswith", relative_path="omio_outputs", zarr_store=None)

# TP004 is present in on one subject only and contains multiple files in its exp folder:
om.bids_batch_convert(fname=PATH_TO_BIDS_PROJECT_FOLDER, sub="ID", exp="TP004",
    exp_match_mode="startswith", relative_path="omio_outputs", zarr_store=None)
# TP004 is present in on one subject only and contains multiple files in its exp folder:
om.bids_batch_convert(fname=PATH_TO_BIDS_PROJECT_FOLDER, sub="ID", exp="TP004",
    exp_match_mode="startswith", relative_path="omio_outputs_merged", zarr_store=None,
    merge_multiple_files_in_folder=True, merge_along_axis="T", zeropadding=True)

# TP005 is present in all subjects and contains a tagged folders in its exp folder:
om.bids_batch_convert(fname=PATH_TO_BIDS_PROJECT_FOLDER, sub="ID", exp="TP005",
    exp_match_mode="startswith", relative_path="../omio_outputs_for_FOV1", zarr_store=None,
    tagfolder="FOV1")
om.bids_batch_convert(fname=PATH_TO_BIDS_PROJECT_FOLDER, sub="ID", exp="TP005",
    exp_match_mode="startswith", relative_path="omio_outputs_for_FOV1_merged", zarr_store=None,
    tagfolder="FOV1", merge_tagfolders=True, merge_along_axis="T", zeropadding=True)


# %% PRINT SUMMARY OF ERRORS
print("\n\n--- SUMMARY OF ERRORS DURING READING/CONVERSION ---")
if len(error_report_collector) == 0:
    print("No errors encountered. All files read and converted successfully.")
else:
    for file_name, error_info in error_report_collector.items():
        print(f"File: {error_info['filepath']}\nTest: {error_info['Test']}\nError: {error_info['error']}\n")

# %% END
