"""
Practice: the code around an agent. Lab 09's idempotency keys (harness.run_tool), the shop side of a
key (world.World.call: "duplicate" and "in_progress") and its approval rule (03_harness.py, Exercise 5).

Fill in the TODOs, then run the tests:
    pytest test_harness_practice.py        (locally)
or press "Run tests" on the chapter page.
"""
import json

WRITE_TOOLS = {"issue_refund", "cancel_order", "update_address"}


def make_key(mode: str | None, run_id: str, call_id: str, tool: str, args: dict) -> str | None:
    """The idempotency key the harness sends with a tool call.
      - mode None:       no key
      - mode "call_id":  f"{run_id}:{call_id}"   (every call gets a fresh ID from the model)
      - mode "content":  f"{run_id}:{tool}:{json.dumps(args, sort_keys=True)}", for write tools only;
                         reads get no key

    TODO 1
    """
    return None


class Shop:
    """The shop side of a slow write. `start` is when a request reaches the payment provider; `finish` is
    when the provider is done, which can be after the harness has stopped waiting."""

    def __init__(self):
        self.refunds = []       # amounts actually refunded
        self.done = set()       # keys whose write finished
        self.running = set()    # keys whose write started and hasn't finished

    def start(self, key: str | None) -> str:
        """A write arrives. Return:
          - "duplicate"    if the key's write already finished (nothing runs again)
          - "in_progress"  if the key's write is still running (refuse the copy)
          - "started"      otherwise; remember a key as running (a write with no key is never tracked)

        TODO 2
        """
        return "started"

    def finish(self, key: str | None, amount: float):
        """The provider finished a started write: record the refund, and mark its key done.

        TODO 3
        """


def needs_person(tool: str, args: dict) -> bool:
    """Which writes pause the run for a person: refunds over $100, and every cancellation.
    Smaller refunds, address changes and every read go straight through.

    TODO 4
    """
    return False
