#!/usr/bin/env python3
"""AAE Lab 09: bounded retries and idempotent side effects."""

class TransientError(RuntimeError):
    pass

attempts = 0

def flaky_read():
    global attempts
    attempts += 1
    if attempts < 3:
        raise TransientError("temporary upstream timeout")
    return {"status": "healthy", "attempt": attempts}


def bounded_retry(fn, max_attempts: int):
    last = None
    for attempt in range(1, max_attempts + 1):
        try:
            return fn()
        except TransientError as exc:
            last = exc
            print(f"retryable failure on attempt {attempt}: {exc}")
    raise RuntimeError(f"retry budget exhausted: {last}")

ledger: set[str] = set()
side_effect_count = 0

def restart_service(idempotency_key: str):
    global side_effect_count
    if idempotency_key in ledger:
        return "duplicate delivery detected; original result reused"
    ledger.add(idempotency_key)
    side_effect_count += 1
    return "restart performed"

print("AAE Lab 09 — bounded retry\n")
result = bounded_retry(flaky_read, max_attempts=3)
print("RESULT:", result)
assert attempts == 3

print("\nAAE Lab 09 — idempotent side effect")
key = "incident-123-step-4"
print(restart_service(key))
print(restart_service(key))
assert side_effect_count == 1
print("✓ Retry stayed within budget.")
print("✓ Duplicate delivery did not duplicate the side effect.")
