import unittest
import midas.client
import midas

"""
Test raising/cancelling alarms.
"""

class TestAlarms(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.client = midas.client.MidasClient("pytest_alarm")
        cls.test_alarm_class = "PyTestAlarmClass"
        cls.test_alarm_names = ["PyTestAlarmA", "PyTestAlarmB"]
        cls.was_alarm_system_active = cls.client.odb_get("/Alarms/Alarm System active")
        cls.client.odb_set("/Alarms/Alarm System active", True)
        
    @classmethod
    def tearDownClass(cls):
        cls.tidy_up_alarms()
        cls.client.odb_set("/Alarms/Alarm System active", cls.was_alarm_system_active)
        cls.client.disconnect()

    @classmethod
    def tidy_up_alarms(cls):
        """
        Search in various locations where the message logs might be.
        If we find a file called "pytest_msg_facility.log", delete it.
        """
        cls.client.odb_delete(f"/Alarms/Classes/{cls.test_alarm_class}")

        for name in cls.test_alarm_names:
            cls.client.odb_delete(f"/Alarms/Alarms/{name}")

    def testAlarmCreateClass(self):
        self.client.create_alarm_class(self.test_alarm_class, stop_run=True)

        odb = self.client.odb_get(f"/Alarms/Classes/{self.test_alarm_class}")

        self.assertEqual(odb["Stop run"], True)

    def testAlarmInternal(self):
        alarm_msg = "Test alarm from python"
        self.client.create_alarm_class(self.test_alarm_class)
        self.client.trigger_internal_alarm(self.test_alarm_names[0], alarm_msg, self.test_alarm_class)

        alarms = self.client.get_triggered_alarms()

        self.assertIn(self.test_alarm_names[0], alarms)
        self.assertEqual(alarms[self.test_alarm_names[0]], alarm_msg)

    def testResetSingleAlarm(self):
        alarm_msg = "Test alarm from python"
        self.client.create_alarm_class(self.test_alarm_class)
        self.client.trigger_internal_alarm(self.test_alarm_names[0], alarm_msg, self.test_alarm_class)

        alarms = self.client.get_triggered_alarms()

        self.assertIn(self.test_alarm_names[0], alarms)

        self.client.reset_alarm(self.test_alarm_names[0])

        alarms = self.client.get_triggered_alarms()

        self.assertNotIn(self.test_alarm_names[0], alarms)

    def testResetAllAlarms(self):
        alarm_msgs = ["Test alarm 1 from python", "Test alarm 2 from python"]
        self.client.create_alarm_class(self.test_alarm_class)
        self.client.trigger_internal_alarm(self.test_alarm_names[0], alarm_msgs[0], self.test_alarm_class)
        self.client.trigger_internal_alarm(self.test_alarm_names[1], alarm_msgs[1], self.test_alarm_class)

        alarms = self.client.get_triggered_alarms()

        self.assertIn(self.test_alarm_names[0], alarms)
        self.assertIn(self.test_alarm_names[1], alarms)

        self.client.reset_all_alarms()

        alarms = self.client.get_triggered_alarms()

        self.assertNotIn(self.test_alarm_names[0], alarms)
        self.assertNotIn(self.test_alarm_names[1], alarms)

    def testInvalidAlarmClassNameLong(self):
        with self.assertRaises(ValueError):
            self.client.create_alarm_class("A"* 40)

    def testInvalidAlarmClassNameSlash(self):
        with self.assertRaises(ValueError):
            self.client.create_alarm_class("A/B")

    def testInvalidAlarmNameLong(self):
        with self.assertRaises(ValueError):
            self.client.trigger_internal_alarm("A"* 40, "message")

    def testInvalidAlarmNameSlash(self):
        with self.assertRaises(ValueError):
            self.client.trigger_internal_alarm("A/B", "message")

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