from datetime import UTC, datetime, timedelta

from worker_watcher.enums import HealthStatus, ObservationStatus, OperationalState
from worker_watcher.models import JobDescriptor
from worker_watcher.normalizer import normalize_status

NOW = datetime(2026, 7, 31, 12, 0, tzinfo=UTC)


def job(**kwargs):
    values = {"job_key": "worker.process.main", "name": "Worker", "source_type": "test", "job_type": "worker", "stale_after_seconds": 60}
    values.update(kwargs)
    return JobDescriptor(**values)


def test_current_heartbeat_healthy() -> None:
    status = normalize_status(job(), {"process_exists": True, "heartbeat_at": NOW - timedelta(seconds=10)}, NOW)
    assert status.health_status == HealthStatus.HEALTHY


def test_old_heartbeat_stale() -> None:
    status = normalize_status(job(), {"process_exists": True, "heartbeat_at": NOW - timedelta(seconds=120)}, NOW)
    assert status.operational_state == OperationalState.RUNNING
    assert status.health_status == HealthStatus.STALE


def test_nonzero_exit_failed() -> None:
    status = normalize_status(job(), {"exit_code": 2}, NOW)
    assert status.health_status == HealthStatus.FAILED


def test_paused_is_not_failed() -> None:
    status = normalize_status(job(), {"paused": True}, NOW)
    assert status.operational_state == OperationalState.PAUSED
    assert status.health_status == HealthStatus.HEALTHY


def test_readable_unknown_is_fresh() -> None:
    status = normalize_status(job(), {}, NOW)
    assert status.health_status == HealthStatus.UNKNOWN
    assert status.observation_status == ObservationStatus.FRESH


def test_unavailable_is_not_job_failure() -> None:
    status = normalize_status(job(), {"permission_denied": True}, NOW)
    assert status.health_status == HealthStatus.UNKNOWN
    assert status.observation_status == ObservationStatus.UNAVAILABLE
