"""Tests for counter total computation with reboot handling."""

from datetime import datetime, timedelta

import pytest

from meshmon.reports import compute_counter_total


class TestComputeCounterTotal:
    """Tests for compute_counter_total function."""

    def test_calculates_total_from_deltas(self, sample_counter_values):
        """Calculates total as sum of positive deltas."""
        total, reboots = compute_counter_total(sample_counter_values)

        # Values: 100, 150, 200, 250, 300
        # Deltas: +50, +50, +50, +50 = 200
        assert total == 200
        assert reboots == 0

    def test_handles_single_value(self):
        """Single value cannot compute delta, returns None."""
        values = [(datetime(2024, 1, 15, 0, 0, 0), 100)]

        total, reboots = compute_counter_total(values)

        assert total is None
        assert reboots == 0

    def test_handles_empty_values(self):
        """Empty values returns None."""
        total, reboots = compute_counter_total([])

        assert total is None
        assert reboots == 0

    def test_detects_single_reboot(self, sample_counter_values_with_reboot):
        """Detects reboot and handles counter reset."""
        total, reboots = compute_counter_total(sample_counter_values_with_reboot)

        # Values: 100, 150, 200, 50 (reboot!), 100
        # Deltas: +50, +50, (reset to 50), +50
        # Total should be: 50 + 50 + 50 + 50 = 200
        # Or: (150-100) + (200-150) + 50 + (100-50) = 200
        assert total == 200
        assert reboots == 1

    def test_handles_multiple_reboots(self):
        """Handles multiple reboots in sequence."""
        base_ts = datetime(2024, 1, 15, 0, 0, 0)
        values = [
            (base_ts, 100),
            (base_ts + timedelta(minutes=15), 150),  # +50
            (base_ts + timedelta(minutes=30), 50),   # Reboot 1
            (base_ts + timedelta(minutes=45), 80),   # +30
            (base_ts + timedelta(hours=1), 30),      # Reboot 2
            (base_ts + timedelta(hours=1, minutes=15), 50),  # +20
        ]

        total, reboots = compute_counter_total(values)

        # Deltas: 50 + 50 + 30 + 30 + 20 = 180
        assert reboots == 2
        assert total == 50 + 50 + 30 + 30 + 20

    def test_zero_delta(self):
        """Handles zero delta (no change)."""
        base_ts = datetime(2024, 1, 15, 0, 0, 0)
        values = [
            (base_ts, 100),
            (base_ts + timedelta(minutes=15), 100),  # No change
            (base_ts + timedelta(minutes=30), 100),  # No change
        ]

        total, reboots = compute_counter_total(values)

        assert total == 0
        assert reboots == 0

    def test_large_values(self):
        """Handles large counter values."""
        base_ts = datetime(2024, 1, 15, 0, 0, 0)
        values = [
            (base_ts, 1000000000),
            (base_ts + timedelta(minutes=15), 1000001000),  # +1000
            (base_ts + timedelta(minutes=30), 1000002500),  # +1500
        ]

        total, reboots = compute_counter_total(values)

        assert total == 2500
        assert reboots == 0

    def test_sorted_values_required(self):
        """Function expects pre-sorted values by timestamp."""
        base_ts = datetime(2024, 1, 15, 0, 0, 0)
        # Properly sorted by timestamp
        values = [
            (base_ts, 100),
            (base_ts + timedelta(minutes=15), 150),
            (base_ts + timedelta(minutes=30), 200),
        ]

        total, reboots = compute_counter_total(values)

        # Deltas: 50, 50 = 100
        assert total == 100
        assert reboots == 0

    def test_two_values(self):
        """Two values gives single delta."""
        base_ts = datetime(2024, 1, 15, 0, 0, 0)
        values = [
            (base_ts, 100),
            (base_ts + timedelta(minutes=15), 175),
        ]

        total, reboots = compute_counter_total(values)

        assert total == 75
        assert reboots == 0

    def test_reboot_to_zero(self):
        """Handles reboot to exactly zero."""
        base_ts = datetime(2024, 1, 15, 0, 0, 0)
        values = [
            (base_ts, 100),
            (base_ts + timedelta(minutes=15), 150),  # +50
            (base_ts + timedelta(minutes=30), 0),    # Reboot to 0
            (base_ts + timedelta(minutes=45), 30),   # +30
        ]

        total, reboots = compute_counter_total(values)

        assert total == 50 + 0 + 30
        assert reboots == 1

    def test_float_values(self):
        """Handles float counter values."""
        base_ts = datetime(2024, 1, 15, 0, 0, 0)
        values = [
            (base_ts, 100.5),
            (base_ts + timedelta(minutes=15), 150.7),
            (base_ts + timedelta(minutes=30), 200.3),
        ]

        total, reboots = compute_counter_total(values)

        expected = (150.7 - 100.5) + (200.3 - 150.7)
        assert total == pytest.approx(expected)
        assert reboots == 0
