# retoor <retoor@molodetz.nl>

from datetime import datetime, timedelta, timezone

from devplacepy.database import get_table
from devplacepy.push import store
from devplacepy.services.push import PushService
from devplacepy.utils import generate_uid


def _registration(user_uid, deleted_at=None, provider="webpush"):
    record = {
        "uid": generate_uid(),
        "user_uid": user_uid,
        "provider": provider,
        "endpoint": f"https://push.example.com/{generate_uid()}",
        "key_auth": "a",
        "key_p256dh": "p",
        "created_at": datetime.now(timezone.utc).isoformat(),
        "deleted_at": deleted_at,
    }
    get_table("push_registration").insert(record)
    return record


def test_config_fields_cover_every_provider(local_db):
    keys = [field.key for field in PushService().all_fields()]
    for expected in (
        "service_push_enabled",
        "push_dead_retention_days",
        "push_delivery_timeout_seconds",
        "push_webpush_enabled",
        "push_webpush_subject",
        "push_apns_enabled",
        "push_apns_team_id",
        "push_apns_key_id",
        "push_apns_auth_key",
        "push_apns_topic",
        "push_apns_environment",
    ):
        assert expected in keys


def test_apns_auth_key_field_is_a_masked_secret(local_db):
    fields = {field.key: field for field in PushService().all_fields()}
    auth_key = fields["push_apns_auth_key"]
    assert auth_key.secret is True
    assert auth_key.type == "text"
    assert auth_key.display_value() == ""


def test_run_once_prunes_only_stale_dead_rows(local_db, monkeypatch):
    from devplacepy.services import push as push_service

    user_uid = f"prune_{generate_uid()}"
    live = _registration(user_uid)
    fresh_dead = _registration(
        user_uid,
        deleted_at=(datetime.now(timezone.utc) - timedelta(days=1)).isoformat(),
    )
    stale_dead = _registration(
        user_uid,
        deleted_at=(datetime.now(timezone.utc) - timedelta(days=90)).isoformat(),
    )

    service = PushService()
    monkeypatch.setattr(
        push_service.service, "get_int_setting", lambda key, default: 30
    )
    from tests.conftest import run_async

    run_async(service.run_once())

    registrations = get_table("push_registration")
    assert registrations.find_one(uid=live["uid"]) is not None
    assert registrations.find_one(uid=fresh_dead["uid"]) is not None
    assert registrations.find_one(uid=stale_dead["uid"]) is None


def test_run_once_with_retention_disabled_prunes_nothing(local_db, monkeypatch):
    from devplacepy.services import push as push_service
    from tests.conftest import run_async

    user_uid = f"keep_{generate_uid()}"
    stale_dead = _registration(
        user_uid,
        deleted_at=(datetime.now(timezone.utc) - timedelta(days=900)).isoformat(),
    )

    service = PushService()
    monkeypatch.setattr(push_service.service, "get_int_setting", lambda key, default: 0)
    run_async(service.run_once())

    assert get_table("push_registration").find_one(uid=stale_dead["uid"]) is not None


def test_metrics_count_live_rows_per_provider(local_db):
    user_uid = f"metrics_{generate_uid()}"
    _registration(user_uid)
    _registration(user_uid, provider="apns")

    metrics = PushService().collect_metrics()
    assert metrics["webpush_active"] >= 1
    assert metrics["apns_active"] >= 1
    assert metrics["webpush_ready"] == 1
    assert "dead" in metrics


def test_store_counts_treats_a_missing_provider_as_webpush(local_db):
    user_uid = f"legacy_{generate_uid()}"
    record = _registration(user_uid)
    get_table("push_registration").update(
        {"id": get_table("push_registration").find_one(uid=record["uid"])["id"], "provider": None},
        ["id"],
    )

    assert store.counts().get("webpush", 0) >= 1
