"""High-value tests for library/download_management/retry_manager.py - Pure logic."""

from datetime import timedelta


from local_deep_research.library.download_management.retry_manager import (
    RetryDecision,
    ResourceFilterResult,
    FilterSummary,
)


# ---------------------------------------------------------------------------
# RetryDecision dataclass
# ---------------------------------------------------------------------------


class TestRetryDecision:
    """RetryDecision dataclass fields."""

    def test_can_retry_true(self):
        d = RetryDecision(can_retry=True)
        assert d.can_retry is True
        assert d.reason is None
        assert d.estimated_wait_time is None

    def test_can_retry_false_with_reason(self):
        d = RetryDecision(can_retry=False, reason="permanently failed")
        assert d.can_retry is False
        assert d.reason == "permanently failed"

    def test_with_estimated_wait(self):
        wait = timedelta(hours=2)
        d = RetryDecision(
            can_retry=False, reason="cooldown", estimated_wait_time=wait
        )
        assert d.estimated_wait_time == wait


# ---------------------------------------------------------------------------
# ResourceFilterResult
# ---------------------------------------------------------------------------


class TestResourceFilterResult:
    """ResourceFilterResult initialization and fields."""

    def test_basic_fields(self):
        r = ResourceFilterResult(
            resource_id=42, can_retry=True, status="available"
        )
        assert r.resource_id == 42
        assert r.can_retry is True
        assert r.status == "available"
        assert r.reason == ""
        assert r.estimated_wait is None

    def test_with_reason_and_wait(self):
        wait = timedelta(minutes=30)
        r = ResourceFilterResult(
            resource_id=1,
            can_retry=False,
            status="temporarily_failed",
            reason="cooldown active",
            estimated_wait=wait,
        )
        assert r.reason == "cooldown active"
        assert r.estimated_wait == wait


# ---------------------------------------------------------------------------
# FilterSummary
# ---------------------------------------------------------------------------


class TestFilterSummary:
    """FilterSummary counting logic."""

    def test_initial_counts_zero(self):
        s = FilterSummary()
        assert s.total_count == 0
        assert s.downloadable_count == 0
        assert s.permanently_failed_count == 0
        assert s.temporarily_failed_count == 0
        assert s.available_count == 0
        assert s.failure_type_counts == {}

    def test_add_downloadable(self):
        s = FilterSummary()
        r = ResourceFilterResult(1, can_retry=True, status="available")
        s.add_result(r)
        assert s.total_count == 1
        assert s.downloadable_count == 1
        assert s.permanently_failed_count == 0

    def test_add_permanently_failed(self):
        s = FilterSummary()
        r = ResourceFilterResult(
            1, can_retry=False, status="permanently_failed"
        )
        s.add_result(r)
        assert s.total_count == 1
        assert s.permanently_failed_count == 1
        assert s.downloadable_count == 0

    def test_add_temporarily_failed(self):
        s = FilterSummary()
        r = ResourceFilterResult(
            1, can_retry=False, status="temporarily_failed"
        )
        s.add_result(r)
        assert s.total_count == 1
        assert s.temporarily_failed_count == 1

    def test_add_unrecognized_status_falls_to_available_counter(self):
        s = FilterSummary()
        r = ResourceFilterResult(1, can_retry=False, status="unavailable")
        s.add_result(r)
        assert s.available_count == 1

    def test_can_retry_true_with_temporarily_failed_status_counts_downloadable(
        self,
    ):
        s = FilterSummary()
        r = ResourceFilterResult(1, can_retry=True, status="temporarily_failed")
        s.add_result(r)
        assert s.downloadable_count == 1
        assert s.temporarily_failed_count == 0

    def test_multiple_results(self):
        s = FilterSummary()
        s.add_result(
            ResourceFilterResult(1, can_retry=True, status="available")
        )
        s.add_result(
            ResourceFilterResult(2, can_retry=True, status="available")
        )
        s.add_result(
            ResourceFilterResult(
                3, can_retry=False, status="permanently_failed"
            )
        )
        s.add_result(
            ResourceFilterResult(
                4, can_retry=False, status="temporarily_failed"
            )
        )
        s.add_result(
            ResourceFilterResult(5, can_retry=False, status="unavailable")
        )

        assert s.total_count == 5
        assert s.downloadable_count == 2
        assert s.permanently_failed_count == 1
        assert s.temporarily_failed_count == 1
        assert s.available_count == 1

    def test_to_dict(self):
        s = FilterSummary()
        s.add_result(
            ResourceFilterResult(1, can_retry=True, status="available")
        )
        s.add_result(
            ResourceFilterResult(2, can_retry=False, status="unavailable")
        )
        d = s.to_dict()
        assert d["total_count"] == 2
        assert d["downloadable_count"] == 1
        assert d["permanently_failed_count"] == 0
        assert d["temporarily_failed_count"] == 0
        assert d["available_count"] == 1
        assert d["failure_type_counts"] == {}
