"""
Practice: pin the tools an agent is given, and check them on every connect. Lab 15's
script 05 (and its pinning.py): a fingerprint of each approved tool, a check that reports
what changed, look-alike names, and the rule for which tools the model may see.

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

# Characters that look alike, folded together when comparing names (get_0rder -> get_order).
CONFUSABLE = str.maketrans({"0": "o", "1": "l", "i": "l", "5": "s", "3": "e", "-": "_", ".": "_"})


def fingerprint(tool):
    """sha256 (hex) of the tool's definition in a canonical form: json.dumps of
    {"name", "description", "schema"} (description defaults to "", schema to the tool's
    "input_schema" or {}), with sort_keys=True and separators=(",", ":")."""
    # TODO
    return ""


def pin(servers):
    """What a person approved. `servers` is {server: [tool, ...]}.
    Return {server: {tool name: {"fingerprint", "description", "schema"}}}."""
    # TODO
    return {}


def skeleton(name):
    """A name reduced to what it looks like: lower case, then CONFUSABLE applied."""
    # TODO
    return name


def check(pins, servers):
    """Findings since approval, as dicts {"kind", "server", "tool"}, in this order:
    1. For each server, in order:
       - not in pins at all: one "new_server" finding (tool None), and nothing else for it;
       - each tool not in its pins: "new_tool";
       - each pinned tool whose fingerprint changed: "changed_description" if its
         description differs, then "changed_schema" if its schema differs;
       - each pinned tool that's gone (sorted by name): "removed_tool".
    2. Name collisions across servers: walk every tool of every server in order; if its
       skeleton matches a tool already seen on a *different* server, add "name_collision"
       for the later tool."""
    # TODO
    return []


def allowed(pins, servers):
    """The rule on connect: the (server, tool) pairs the model may see. A tool is allowed
    only if it's pinned, and no finding names it (and its server has no finding with
    tool None). Everything else stays switched off until a person reviews it."""
    # TODO
    return set()
