"""
Exercise 1: __enter__ / __exit__ protocol and exception suppression

STEP 1: Implement `Transaction`, a class-based context manager over a
        module-level list `LOG` (acting as a fake database):
          - __init__(self, name): store self.name
          - __enter__(self): append f"{self.name}: begin" to LOG, return self
          - __exit__(self, exc_type, exc_value, traceback):
              - if exc_type is None: append f"{self.name}: commit" to LOG,
                return False
              - if exc_type is ValueError: append f"{self.name}: rollback
                (suppressed)" to LOG, return True (suppress ONLY ValueError)
              - any other exception type: append f"{self.name}: rollback
                (propagated)" to LOG, return False (let it propagate)

STEP 2: Implement `run_transaction(name, should_raise)` — inside a
        `with Transaction(name) as t:` block, if `should_raise` is not
        None, `raise should_raise("boom")`. Return the string "completed"
        if the block finished (whether normally or via a suppressed
        exception). Let any NON-suppressed exception propagate out of
        this function.
"""

LOG = []


class Transaction:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        # TODO: append f"{self.name}: begin" to LOG, return self
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        # TODO: implement the three-way branch described in STEP 1
        pass


def run_transaction(name, should_raise=None):
    # TODO: use `with Transaction(name) as t:`, raise should_raise("boom")
    # if should_raise is not None, return "completed" if the with block
    # exits (normally or via suppression)
    pass


# --- self-check: do not modify below this line ---
checks = []

LOG.clear()
result = run_transaction("tx1", should_raise=None)
checks.append(("normal transaction returns 'completed'", result, "completed"))
checks.append(("normal transaction logs begin+commit", list(LOG), ["tx1: begin", "tx1: commit"]))

LOG.clear()
result2 = run_transaction("tx2", should_raise=ValueError)
checks.append(("ValueError is suppressed, function still returns 'completed'", result2, "completed"))
checks.append(("suppressed transaction logs begin+rollback(suppressed)",
                list(LOG), ["tx2: begin", "tx2: rollback (suppressed)"]))

LOG.clear()
propagated = None
try:
    run_transaction("tx3", should_raise=TypeError)
except TypeError as e:
    propagated = e
checks.append(("TypeError is NOT suppressed, propagates out", isinstance(propagated, TypeError), True))
checks.append(("non-suppressed transaction logs begin+rollback(propagated)",
                list(LOG), ["tx3: begin", "tx3: rollback (propagated)"]))

passed = 0
for label, actual, expected in checks:
    ok = actual == expected
    passed += ok
    print(f"{'PASS' if ok else 'FAIL'}: {label} (got {actual!r}, expected {expected!r})")

print("PASS" if passed == len(checks) else "FAIL")
