"""
Tests for sentry functionality.
"""
import unittest
from preseem.sentry import SentryClient, SentryLog
from time import monotonic


class MockSentryClient(SentryClient):
    """A mock client to log errors or messages to Sentry."""

    def __init__(self, sentry_key, server_name: str):
        self.logs = {}


class TestSentryClient(unittest.TestCase):
    """Tests for Sentry Client."""

    def mock_add_log_side_effect(logs, log_type, frequency, description, tags={}):
        """Mock SentryClient._add_log"""
        log = SentryLog(log_type, str(tags), frequency, str(description))
        log_time = int(monotonic())
        last_log_time = logs.get(log)
        if not last_log_time or log_time - last_log_time >= frequency:
            if frequency > 0:
                logs[log] = log_time

    @unittest.mock.patch('preseem.sentry.SentryClient._add_log',
                         side_effect=mock_add_log_side_effect)
    def test_get_brmacs(self, mock_add_log):
        """Test logging error and message has monotonic log time."""
        sentry_client = MockSentryClient("Test Key", "Test Server")
        last_test_case = 0
        start_time = int(monotonic())

        test_log1 = SentryLog("err", "{}", 10, '1')
        test_log2 = SentryLog("msg", "{}", 0, '2')

        while (True):
            now = int(monotonic()) - start_time
            if now < 5 and last_test_case < 1:
                assert (sentry_client.logs.get(test_log1) is None)
                assert (sentry_client.logs.get(test_log2) is None)
                mock_add_log(sentry_client.logs, "err", 10, "1")
                mock_add_log(sentry_client.logs, "msg", 0, "2")
                assert (sentry_client.logs.get(test_log1) is not None)
                assert (sentry_client.logs.get(test_log2) is None)
                assert (sentry_client.logs.get(test_log1) >= now)
                last_test_case = 1
            elif 5 <= now < 10 and last_test_case < 2:
                assert (sentry_client.logs.get(test_log1) is not None)
                assert (sentry_client.logs.get(test_log2) is None)
                log_time_before = sentry_client.logs[test_log1]
                mock_add_log(sentry_client.logs, "err", 10, "1")
                mock_add_log(sentry_client.logs, "msg", 0, "2")
                assert (sentry_client.logs.get(test_log1) is not None)
                assert (sentry_client.logs.get(test_log2) is None)
                assert (sentry_client.logs[test_log1] == log_time_before)
                last_test_case = 2
            elif 10 <= now < 15 and last_test_case < 3:
                assert (sentry_client.logs.get(test_log1) is not None)
                log_time_before = sentry_client.logs[test_log1]
                mock_add_log(sentry_client.logs, "err", 10, "1")
                assert (sentry_client.logs.get(test_log1) is not None)
                assert (sentry_client.logs.get(test_log1) >= log_time_before)
                assert (sentry_client.logs.get(test_log1) >= now)
                last_test_case = 3
            elif now >= 15:
                break
