from typing import Any
from typing import Dict
from typing import List
from typing import Tuple

from . import assert_results


def test_multi_scan_multi_detector_without_qt(tmp_path):
    assert_results.assert_without_qt(
        "mesh_stack_multi_detector.ows",
        get_inputs(tmp_path),
        get_expected_outputs(tmp_path),
        get_expected_hdf5(tmp_path),
    )


def test_multi_scan_multi_detector_with_qt(ewoks_orange_canvas, tmp_path):
    assert_results.assert_with_qt(
        ewoks_orange_canvas,
        "mesh_stack_multi_detector.ows",
        get_inputs(tmp_path),
        get_expected_outputs(tmp_path),
        get_expected_hdf5(tmp_path),
    )


def get_inputs(tmp_path) -> List[Dict[str, Any]]:
    return [
        {
            "label": "Mesh stack (multi detector)",
            "name": "output_filename",
            "value": str(tmp_path / "input.h5"),
        },
        {
            "label": "Fit stack (multi detector)",
            "name": "output_root_uri",
            "value": str(tmp_path / "output.h5::/1.1"),
        },
    ]


def get_expected_outputs(tmp_path) -> Dict[str, Dict[str, Any]]:
    bliss_scan_uris = [str(tmp_path / f"input.h5::/{i}.1") for i in range(1, 4)]
    output_root_uri = str(tmp_path / "output.h5::/1.1")
    return {
        "Mesh stack (multi detector)": {
            "config": str(tmp_path / "input.h5::/1.1/theory/configuration/data"),
            "configs": [str(tmp_path / "input.h5::/1.1/theory/configuration/data")] * 2,
            "detector_names": ["mca0", "mca1"],
            "expo_time": 0.1,
            "filenames": [str(tmp_path / "input.h5")],
            "monitor_name": "I0",
            "monitor_normalization_template": "1000000/<instrument/{}/data>",
            "detector_normalization_template": "0.1/<instrument/{}/live_time>",
            "scan_ranges": [(1, 3)],
        },
        "Pick scans": {"bliss_scan_uris": bliss_scan_uris},
        "Fit stack (multi detector)": {
            "xrf_results_uris": [
                str(tmp_path / "output.h5::/1.1/fit/mca0/results"),
                str(tmp_path / "output.h5::/1.1/fit/mca1/results"),
            ],
            "bliss_scan_uris": bliss_scan_uris,
            "detector_names": ["mca0", "mca1"],
            "output_root_uri": output_root_uri,
            "output_root_group": None,
        },
        "Sum Fit Results Stack": {
            "xrf_results_uri": str(tmp_path / "output.h5::/1.1/sum/results"),
            "bliss_scan_uris": bliss_scan_uris,
            "output_root_uri": output_root_uri,
            "output_root_group": None,
        },
        "Normalize Stack": {
            "xrf_results_uri": str(tmp_path / "output.h5::/1.1/norm/results"),
            "bliss_scan_uris": bliss_scan_uris,
            "output_root_uri": output_root_uri,
            "output_root_group": None,
        },
        "Raw Counters Stack": {
            "xrf_results_uri": str(tmp_path / "output.h5::/1.1/merge/results"),
            "bliss_scan_uris": bliss_scan_uris,
            "output_root_uri": output_root_uri,
            "output_root_group": None,
        },
        "Regrid Stack": {
            "xrf_results_uri": str(tmp_path / "output.h5::/1.1/regrid/results"),
            "bliss_scan_uris": bliss_scan_uris,
            "output_root_uri": output_root_uri,
            "output_root_group": None,
        },
    }


def get_expected_hdf5(tmp_path) -> Tuple[str, Dict[str, Any]]:
    output_path = tmp_path / "output.h5"
    expected = {
        "@NX_class": "NXroot",
        "@extra_attrs": {"default"},
        "1.1": {
            "@NX_class": "NXentry",
            "@extra_attrs": {"default"},
            "end_time@shape": (),
            "fit": {
                "@NX_class": "NXcollection",
                "@extra_attrs": {"default"},
                "mca0": {
                    "@NX_class": "NXprocess",
                    "@extra_attrs": {"default"},
                    "configuration": {
                        "@NX_class": "NXnote",
                        "data@shape": (),
                        "date@shape": (),
                        "type@shape": (),
                    },
                    "program@shape": (),
                    "results": {
                        "@NX_class": "NXcollection",
                        "@extra_attrs": {"default"},
                        "parameters": {
                            "@NX_class": "NXdata",
                            "@signals": {
                                "Fe_K",
                                "Scatter_Peak000",
                                "Ce_L",
                                "Si_K",
                                "Scatter_Compton000",
                                "Ca_K",
                            },
                            "Ca_K@shape": (3, 3000),
                            "Ce_L@shape": (3, 3000),
                            "Fe_K@shape": (3, 3000),
                            "Scatter_Compton000@shape": (3, 3000),
                            "Scatter_Peak000@shape": (3, 3000),
                            "Si_K@shape": (3, 3000),
                        },
                        "uncertainties": {
                            "@NX_class": "NXdata",
                            "@signals": {
                                "Fe_K",
                                "Scatter_Peak000",
                                "Ce_L",
                                "Si_K",
                                "Scatter_Compton000",
                                "Ca_K",
                            },
                            "Ca_K@shape": (3, 3000),
                            "Ce_L@shape": (3, 3000),
                            "Fe_K@shape": (3, 3000),
                            "Scatter_Compton000@shape": (3, 3000),
                            "Scatter_Peak000@shape": (3, 3000),
                            "Si_K@shape": (3, 3000),
                        },
                    },
                    "version@shape": (),
                },
                "mca1": {
                    "@NX_class": "NXprocess",
                    "@extra_attrs": {"default"},
                    "configuration": {
                        "@NX_class": "NXnote",
                        "data@shape": (),
                        "date@shape": (),
                        "type@shape": (),
                    },
                    "program@shape": (),
                    "results": {
                        "@NX_class": "NXcollection",
                        "@extra_attrs": {"default"},
                        "parameters": {
                            "@NX_class": "NXdata",
                            "@signals": {
                                "Fe_K",
                                "Scatter_Peak000",
                                "Ce_L",
                                "Si_K",
                                "Scatter_Compton000",
                                "Ca_K",
                            },
                            "Ca_K@shape": (3, 3000),
                            "Ce_L@shape": (3, 3000),
                            "Fe_K@shape": (3, 3000),
                            "Scatter_Compton000@shape": (3, 3000),
                            "Scatter_Peak000@shape": (3, 3000),
                            "Si_K@shape": (3, 3000),
                        },
                        "uncertainties": {
                            "@NX_class": "NXdata",
                            "@signals": {
                                "Fe_K",
                                "Scatter_Peak000",
                                "Ce_L",
                                "Si_K",
                                "Scatter_Compton000",
                                "Ca_K",
                            },
                            "Ca_K@shape": (3, 3000),
                            "Ce_L@shape": (3, 3000),
                            "Fe_K@shape": (3, 3000),
                            "Scatter_Compton000@shape": (3, 3000),
                            "Scatter_Peak000@shape": (3, 3000),
                            "Si_K@shape": (3, 3000),
                        },
                    },
                    "version@shape": (),
                },
            },
            "merge": {
                "@NX_class": "NXprocess",
                "@extra_attrs": {"default"},
                "configuration": {
                    "@NX_class": "NXnote",
                    "data@shape": (),
                    "date@shape": (),
                    "type@shape": (),
                },
                "program@shape": (),
                "results": {
                    "@NX_class": "NXcollection",
                    "@extra_attrs": {"default"},
                    "parameters": {
                        "@NX_class": "NXdata",
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 3000),
                        "Ce_L@shape": (3, 3000),
                        "Fe_K@shape": (3, 3000),
                        "Scatter_Compton000@shape": (3, 3000),
                        "Scatter_Peak000@shape": (3, 3000),
                        "Si_K@shape": (3, 3000),
                    },
                    "rawcounters": {
                        "@NX_class": "NXdata",
                        "@signals": {
                            "mca0_events",
                            "mca1_live_time",
                            "mca0_trigger_live_time",
                            "I0",
                            "mca0_elapsed_time",
                            "sampy",
                            "mca1_trigger_count_rate",
                            "mca1_elapsed_time",
                            "mca1_triggers",
                            "mca1_roi1",
                            "mca0_fractional_dead_time",
                            "mca1_trigger_live_time",
                            "mca1_event_count_rate",
                            "mca0_roi2",
                            "mca1_roi2",
                            "mca0_event_count_rate",
                            "mca0_triggers",
                            "mca1_events",
                            "mca0_live_time",
                            "mca0_roi1",
                            "mca0_trigger_count_rate",
                            "mca1_fractional_dead_time",
                            "sampz",
                        },
                        "I0@shape": (3, 3000),
                        "mca0_elapsed_time@shape": (3, 3000),
                        "mca0_event_count_rate@shape": (3, 3000),
                        "mca0_events@shape": (3, 3000),
                        "mca0_fractional_dead_time@shape": (3, 3000),
                        "mca0_live_time@shape": (3, 3000),
                        "mca0_roi1@shape": (3, 3000),
                        "mca0_roi2@shape": (3, 3000),
                        "mca0_trigger_count_rate@shape": (3, 3000),
                        "mca0_trigger_live_time@shape": (3, 3000),
                        "mca0_triggers@shape": (3, 3000),
                        "mca1_elapsed_time@shape": (3, 3000),
                        "mca1_event_count_rate@shape": (3, 3000),
                        "mca1_events@shape": (3, 3000),
                        "mca1_fractional_dead_time@shape": (3, 3000),
                        "mca1_live_time@shape": (3, 3000),
                        "mca1_roi1@shape": (3, 3000),
                        "mca1_roi2@shape": (3, 3000),
                        "mca1_trigger_count_rate@shape": (3, 3000),
                        "mca1_trigger_live_time@shape": (3, 3000),
                        "mca1_triggers@shape": (3, 3000),
                        "sampy@shape": (3, 3000),
                        "sampz@shape": (3, 3000),
                    },
                    "uncertainties": {
                        "@NX_class": "NXdata",
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 3000),
                        "Ce_L@shape": (3, 3000),
                        "Fe_K@shape": (3, 3000),
                        "Scatter_Compton000@shape": (3, 3000),
                        "Scatter_Peak000@shape": (3, 3000),
                        "Si_K@shape": (3, 3000),
                    },
                },
                "version@shape": (),
            },
            "norm": {
                "@NX_class": "NXprocess",
                "@extra_attrs": {"default"},
                "configuration": {
                    "@NX_class": "NXnote",
                    "data@shape": (),
                    "date@shape": (),
                    "type@shape": (),
                },
                "program@shape": (),
                "results": {
                    "@NX_class": "NXcollection",
                    "@extra_attrs": {"default"},
                    "parameters": {
                        "@NX_class": "NXdata",
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 3000),
                        "Ce_L@shape": (3, 3000),
                        "Fe_K@shape": (3, 3000),
                        "Scatter_Compton000@shape": (3, 3000),
                        "Scatter_Peak000@shape": (3, 3000),
                        "Si_K@shape": (3, 3000),
                    },
                    "uncertainties": {
                        "@NX_class": "NXdata",
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 3000),
                        "Ce_L@shape": (3, 3000),
                        "Fe_K@shape": (3, 3000),
                        "Scatter_Compton000@shape": (3, 3000),
                        "Scatter_Peak000@shape": (3, 3000),
                        "Si_K@shape": (3, 3000),
                    },
                },
                "version@shape": (),
            },
            "regrid": {
                "@NX_class": "NXprocess",
                "@extra_attrs": {"default"},
                "configuration": {
                    "@NX_class": "NXnote",
                    "data@shape": (),
                    "date@shape": (),
                    "type@shape": (),
                },
                "program@shape": (),
                "results": {
                    "@NX_class": "NXcollection",
                    "@extra_attrs": {"default"},
                    "coordinates": {
                        "@NX_class": "NXcollection",
                        "closest_grid_distance": {
                            "@NX_class": "NXdata",
                            "@axes": ["sampy", "sampz"],
                            "@signals": {"distance"},
                            "distance@shape": (3000,),
                            "sampy@shape": (3000,),
                            "sampy@long_name": "sampy (um)",
                            "sampy@units": "um",
                            "sampz@shape": (3000,),
                            "sampz@long_name": "sampz (um)",
                            "sampz@units": "um",
                            "title@shape": (),
                        },
                        "closest_scatter_distance": {
                            "@NX_class": "NXdata",
                            "@axes": ["sampy", "sampz"],
                            "@signals": {"distance"},
                            "distance@shape": (3630,),
                            "sampy@shape": (3630,),
                            "sampy@long_name": "sampy (um)",
                            "sampy@units": "um",
                            "sampz@shape": (3630,),
                            "sampz@long_name": "sampz (um)",
                            "sampz@units": "um",
                            "title@shape": (),
                        },
                        "coordinates": {
                            "@NX_class": "NXdata",
                            "@axes": ["sampy", "sampz"],
                            "@signals": {"coordinate_type"},
                            "coordinate_type@shape": (6630,),
                            "sampy@shape": (6630,),
                            "sampy@long_name": "sampy (um)",
                            "sampy@units": "um",
                            "sampz@shape": (6630,),
                            "sampz@long_name": "sampz (um)",
                            "sampz@units": "um",
                            "title@shape": (),
                        },
                        "grid_coordinates": {
                            "@NX_class": "NXdata",
                            "@axes": ["sampy", "sampz"],
                            "@signals": {"has_data"},
                            "has_data@shape": (3630,),
                            "sampy@shape": (3630,),
                            "sampy@long_name": "sampy (um)",
                            "sampy@units": "um",
                            "sampz@shape": (3630,),
                            "sampz@long_name": "sampz (um)",
                            "sampz@units": "um",
                            "title@shape": (),
                        },
                        "scatter_coordinates": {
                            "@NX_class": "NXdata",
                            "@axes": ["sampy", "sampz"],
                            "@signals": {"indices"},
                            "indices@shape": (3000,),
                            "sampy@shape": (3000,),
                            "sampy@long_name": "sampy (um)",
                            "sampy@units": "um",
                            "sampz@shape": (3000,),
                            "sampz@long_name": "sampz (um)",
                            "sampz@units": "um",
                            "title@shape": (),
                        },
                    },
                    "parameters": {
                        "@NX_class": "NXdata",
                        "@axes": ["energy", "sampz", "sampy"],
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 55, 66),
                        "Ce_L@shape": (3, 55, 66),
                        "Fe_K@shape": (3, 55, 66),
                        "Scatter_Compton000@shape": (3, 55, 66),
                        "Scatter_Peak000@shape": (3, 55, 66),
                        "Si_K@shape": (3, 55, 66),
                        "energy@shape": (3,),
                        "energy@long_name": "energy (keV)",
                        "energy@units": "keV",
                        "energy_indices@shape": (),
                        "sampy@shape": (66,),
                        "sampy@long_name": "sampy (um)",
                        "sampy@units": "um",
                        "sampy_indices@shape": (),
                        "sampz@shape": (55,),
                        "sampz@long_name": "sampz (um)",
                        "sampz@units": "um",
                        "sampz_indices@shape": (),
                    },
                    "rawcounters": {
                        "@NX_class": "NXdata",
                        "@axes": ["energy", "sampz", "sampy"],
                        "@signals": {
                            "mca0_events",
                            "mca1_live_time",
                            "mca0_trigger_live_time",
                            "I0",
                            "mca0_elapsed_time",
                            "mca1_trigger_count_rate",
                            "mca1_elapsed_time",
                            "mca1_triggers",
                            "mca1_roi1",
                            "mca0_fractional_dead_time",
                            "mca1_trigger_live_time",
                            "mca1_event_count_rate",
                            "mca0_roi2",
                            "mca1_roi2",
                            "mca0_event_count_rate",
                            "mca0_triggers",
                            "mca1_events",
                            "mca0_live_time",
                            "mca0_roi1",
                            "mca0_trigger_count_rate",
                            "mca1_fractional_dead_time",
                        },
                        "I0@shape": (3, 55, 66),
                        "energy@shape": (3,),
                        "energy@long_name": "energy (keV)",
                        "energy@units": "keV",
                        "energy_indices@shape": (),
                        "mca0_elapsed_time@shape": (3, 55, 66),
                        "mca0_event_count_rate@shape": (3, 55, 66),
                        "mca0_events@shape": (3, 55, 66),
                        "mca0_fractional_dead_time@shape": (3, 55, 66),
                        "mca0_live_time@shape": (3, 55, 66),
                        "mca0_roi1@shape": (3, 55, 66),
                        "mca0_roi2@shape": (3, 55, 66),
                        "mca0_trigger_count_rate@shape": (3, 55, 66),
                        "mca0_trigger_live_time@shape": (3, 55, 66),
                        "mca0_triggers@shape": (3, 55, 66),
                        "mca1_elapsed_time@shape": (3, 55, 66),
                        "mca1_event_count_rate@shape": (3, 55, 66),
                        "mca1_events@shape": (3, 55, 66),
                        "mca1_fractional_dead_time@shape": (3, 55, 66),
                        "mca1_live_time@shape": (3, 55, 66),
                        "mca1_roi1@shape": (3, 55, 66),
                        "mca1_roi2@shape": (3, 55, 66),
                        "mca1_trigger_count_rate@shape": (3, 55, 66),
                        "mca1_trigger_live_time@shape": (3, 55, 66),
                        "mca1_triggers@shape": (3, 55, 66),
                        "sampy@shape": (66,),
                        "sampy@long_name": "sampy (um)",
                        "sampy@units": "um",
                        "sampy_indices@shape": (),
                        "sampz@shape": (55,),
                        "sampz@long_name": "sampz (um)",
                        "sampz@units": "um",
                        "sampz_indices@shape": (),
                    },
                    "title@shape": (),
                    "uncertainties": {
                        "@NX_class": "NXdata",
                        "@axes": ["energy", "sampz", "sampy"],
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 55, 66),
                        "Ce_L@shape": (3, 55, 66),
                        "Fe_K@shape": (3, 55, 66),
                        "Scatter_Compton000@shape": (3, 55, 66),
                        "Scatter_Peak000@shape": (3, 55, 66),
                        "Si_K@shape": (3, 55, 66),
                        "energy@shape": (3,),
                        "energy@long_name": "energy (keV)",
                        "energy@units": "keV",
                        "energy_indices@shape": (),
                        "sampy@shape": (66,),
                        "sampy@long_name": "sampy (um)",
                        "sampy@units": "um",
                        "sampy_indices@shape": (),
                        "sampz@shape": (55,),
                        "sampz@long_name": "sampz (um)",
                        "sampz@units": "um",
                        "sampz_indices@shape": (),
                    },
                },
                "version@shape": (),
            },
            "start_time@shape": (),
            "sum": {
                "@NX_class": "NXprocess",
                "@extra_attrs": {"default"},
                "configuration": {
                    "@NX_class": "NXnote",
                    "data@shape": (),
                    "date@shape": (),
                    "type@shape": (),
                },
                "program@shape": (),
                "results": {
                    "@NX_class": "NXcollection",
                    "@extra_attrs": {"default"},
                    "parameters": {
                        "@NX_class": "NXdata",
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 3000),
                        "Ce_L@shape": (3, 3000),
                        "Fe_K@shape": (3, 3000),
                        "Scatter_Compton000@shape": (3, 3000),
                        "Scatter_Peak000@shape": (3, 3000),
                        "Si_K@shape": (3, 3000),
                    },
                    "uncertainties": {
                        "@NX_class": "NXdata",
                        "@signals": {
                            "Fe_K",
                            "Scatter_Peak000",
                            "Ce_L",
                            "Si_K",
                            "Scatter_Compton000",
                            "Ca_K",
                        },
                        "Ca_K@shape": (3, 3000),
                        "Ce_L@shape": (3, 3000),
                        "Fe_K@shape": (3, 3000),
                        "Scatter_Compton000@shape": (3, 3000),
                        "Scatter_Peak000@shape": (3, 3000),
                        "Si_K@shape": (3, 3000),
                    },
                },
                "version@shape": (),
            },
        },
    }
    return output_path, expected
