"""Normative r71b package-binding and hold derivation contracts."""

from __future__ import annotations

from datetime import date, datetime

import pytest
from pydantic import ValidationError

from gateway.platforms.nutrition_weekly_maintenance_contract import (
    Topic59MaintenanceHoldV1,
    Topic59MaintenanceScopeV1,
    derive_hold_id,
    maintenance_scope_digest,
)


def test_hold_uses_binding_digest_and_nested_scope_without_final_digest() -> None:
    # Given
    scope = {
        "schema": "nutricoach-r71b-maintenance-scope-v1",
        "product_generation": "r71",
        "package_namespace": "r71b-maintenance",
        "authority_id": "nutricoach-v150-v15-runtime-authority-r71b-maintenance",
        "credential_name": "nutricoach-topic59-maintenance-r71b.json",
        "purpose": "r71_cron_health_recovery",
        "max_consumptions": 1,
        "candidate_digest": "1" * 64,
        "config_digest": "2" * 64,
        "route_digest": "3" * 64,
        "customer_identity_digest": "4" * 64,
        "card_slot": "5" * 64,
        "kst_day": date(2026, 9, 1),
        "not_before": datetime.fromisoformat("2026-09-01T16:00:00+09:00"),
        "expires_at": datetime.fromisoformat("2026-09-01T16:10:00+09:00"),
        "active_hold_relative_path": "data/topic59-maintenance-r71b/hold.json",
        "consuming_hold_relative_path": "data/topic59-maintenance-r71b/hold.consuming.json",
        "terminal_audit_relative_path": "data/topic59-maintenance-r71b/skip-audit.json",
        "lock_relative_path": "data/topic59-maintenance-r71b/maintenance.lock",
    }

    # When
    parsed_scope = Topic59MaintenanceScopeV1.model_validate(scope)
    binding_digest = "7" * 64
    hold = Topic59MaintenanceHoldV1(
        hold_id=derive_hold_id(binding_digest, maintenance_scope_digest(parsed_scope)),
        package_binding_digest=binding_digest,
        scope=parsed_scope,
    )

    # Then
    document = hold.model_dump(mode="json", by_alias=True)
    assert document["package_binding_digest"] == "7" * 64
    assert document["scope"] == {
        **scope,
        "kst_day": "2026-09-01",
        "not_before": "2026-09-01T16:00:00+09:00",
        "expires_at": "2026-09-01T16:10:00+09:00",
    }
    assert "package_digest" not in document
    with pytest.raises(ValidationError):
        Topic59MaintenanceHoldV1.model_validate({
            **document,
            "package_digest": "8" * 64,
        })
