# Filename: test_online.py
# pylint: disable=locally-disabled,C0111,R0904,C0301,C0103,W0212
from km3pipe.testing import TestCase, patch, skip, data_path
import sys
import numpy as np
from km3pipe.io.online import EventPump, TimeslicePump
from km3pipe.io.hdf5 import HDF5Pump
from os.path import join, dirname, abspath

__author__ = "Tamas Gal"
__copyright__ = "Copyright 2018, Tamas Gal and the KM3NeT collaboration."
__credits__ = []
__license__ = "MIT"
__maintainer__ = "Tamas Gal, Johannes Schumann"
__email__ = "tgal@km3net.de"
__status__ = "Development"

ONLINE_TEST_FILE = data_path("online/events_sample.root")
ONLINE_TEST_FILE_H5 = data_path("online/events_sample.h5")


class TestEventPump(TestCase):
    def setUp(self):
        self.jpp_pump = EventPump(filename=ONLINE_TEST_FILE)
        self.h5_pump = HDF5Pump(filename=ONLINE_TEST_FILE_H5)

    def tearDown(self):
        self.jpp_pump.finish()
        self.h5_pump.finish()

    def test_event_info(self):
        n = self.jpp_pump.n_events
        for i in range(n):
            h5blob = self.h5_pump[i]
            jppblob = self.jpp_pump[i]
            for k in h5blob["EventInfo"].dtype.names:
                if k not in jppblob["EventInfo"].dtype.names:
                    continue
                ref_value = h5blob["EventInfo"][k][0]
                test_value = jppblob["EventInfo"][k][0]
                if isinstance(ref_value, float):
                    if np.isnan(ref_value):
                        assert np.isnan(test_value) == np.isnan(ref_value)
                    else:
                        self.assertAlmostEqual(test_value, ref_value)
                else:
                    assert ref_value == test_value

    @skip
    def test_hit_info(self):
        n = self.jpp_pump.n_events
        for i in range(n):
            h5blob = self.h5_pump[i]
            jppblob = self.jpp_pump[i]
            for k in h5blob["Hits"].dtype.names:
                ref_value = h5blob["Hits"][k][0]
                test_value = jppblob["Hits"][k][0]
                if isinstance(ref_value, float):
                    if np.isnan(ref_value):
                        assert np.isnan(test_value)
                    else:
                        self.assertAlmostEqual(test_value, ref_value)
                else:
                    assert ref_value == test_value


class TestTimeslicePump(TestCase):
    def setUp(self):
        self.jpp_fname = ONLINE_TEST_FILE
        self.timeslice_pump = TimeslicePump(filename=self.jpp_fname, stream="L1")

    def test_timeslice_info(self):
        blob = self.timeslice_pump[0]
        tsinfo = blob["TimesliceInfo"]
        assert tsinfo.frame_index == 366
        assert tsinfo.slice_id == 0
        assert tsinfo.timestamp == 1575979236
        assert tsinfo.nanoseconds == 600000000
        assert tsinfo.n_frames == 69

    def test_timeslice_hits(self):
        blob = self.timeslice_pump[0]
        l1hits = blob["L1Hits"]
        counts = [
            1421,
            1272,
            1533,
            1209,
            1311,
            1450,
            1102,
            1494,
            1410,
            1390,
            1225,
            1419,
            1474,
            1452,
            1589,
            1362,
            1577,
            1598,
            1891,
            1584,
            1571,
            1523,
            1696,
            1719,
            1540,
            1578,
            1656,
            1569,
            1422,
            1401,
            1262,
        ]
        tot = [
            216,
            681,
            1222,
            1580,
            1484,
            1221,
            940,
            887,
            908,
            950,
            844,
            736,
            717,
            661,
            752,
            716,
            791,
            946,
            1089,
            1220,
            1484,
            1786,
            2265,
            2539,
            2932,
            3132,
            3201,
            2901,
            2403,
            1654,
            1056,
            566,
            297,
            167,
            94,
            74,
            82,
            60,
            50,
            37,
            30,
            24,
            24,
            20,
            19,
            12,
            15,
            15,
            13,
            8,
            5,
            6,
            9,
            9,
            7,
            9,
            11,
            6,
            5,
            10,
            7,
            4,
            7,
            2,
            7,
            1,
            4,
            5,
            5,
            3,
            3,
            3,
            2,
            3,
            2,
            3,
            1,
            4,
            3,
            4,
            1,
            1,
            2,
            2,
            1,
            2,
            3,
            1,
            1,
            1,
            2,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
        ]
        dom_id = [
            774,
            244,
            602,
            935,
            533,
            878,
            862,
            699,
            760,
            1058,
            625,
            641,
            621,
            679,
            912,
            461,
            925,
            633,
            754,
            701,
            767,
            784,
            812,
            299,
            605,
            1010,
            226,
            892,
            785,
            864,
            707,
            540,
            749,
            772,
            172,
            748,
            773,
            585,
            278,
            656,
            852,
            685,
            1041,
            473,
            639,
            695,
            837,
            830,
            656,
            676,
            486,
            647,
            533,
            716,
            649,
            599,
            502,
            271,
            629,
            769,
            613,
            784,
            705,
            600,
            984,
            682,
            243,
            583,
        ]
        self.assertListEqual(
            counts, np.unique(l1hits.channel_id, return_counts=True)[1].tolist()
        )
        self.assertListEqual(tot, np.unique(l1hits.tot, return_counts=True)[1].tolist())
        self.assertListEqual(
            dom_id, np.unique(l1hits.dom_id, return_counts=True)[1].tolist()
        )
