import importlib.util
from pathlib import Path
import unittest

path = Path(__file__).resolve().parents[1] / 'app/fight_r5/notification.py'
spec = importlib.util.spec_from_file_location('notification', path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)


class NotificationTests(unittest.TestCase):
    def test_two_second_boundary(self):
        state = module.NotificationState()
        self.assertTrue(state.observe(0., True))
        state.admitted(10.)
        state.observe(1.999, False)
        self.assertTrue(state.latched)
        self.assertFalse(state.observe(2., False))
        self.assertFalse(state.latched)

    def test_denial_does_not_consume_candidate(self):
        state = module.NotificationState()
        state.observe(0., True)
        state.denied()
        self.assertFalse(state.latched)
        self.assertIsNone(state.last_issued)
        self.assertTrue(state.observe(.1, True))

    def test_continuous_hits_remain_eligible(self):
        state = module.NotificationState()
        state.observe(0., True)
        state.admitted(0.)
        for i in range(1, 101):
            self.assertTrue(state.observe(i/10, True))
        self.assertEqual(state.last_issued, 0.)

    def test_missing_is_not_an_event(self):
        state = module.NotificationState()
        state.observe(0., True)
        state.admitted(0.)
        for i in range(1, 6001):
            self.assertFalse(state.observe(i/10, False))
        self.assertFalse(state.latched)
        self.assertEqual(state.last_issued, 0.)

    def test_stale_is_rejected(self):
        state = module.NotificationState()
        state.observe(1., True)
        for value in (1., .5, float('nan')):
            with self.assertRaises(ValueError):
                state.observe(value, True)


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