"""Does the model follow the tutorial's rules, whatever order the moves come in?

    python wording.py [address]

Two files have their own words. For ask.py (and hunt.py, which has the same words): the
four things hunt.py's sees() can say, each with the three moves in all six orders. For
agent.py: its two sentences, each with its two moves in both orders. 28 questions.

ask.py asks its own address, or the one given. agent.py runs the model itself: with the
decider-ai library installed it does that here too, and without it the questions go to the
same address (see agent_file.py).

The wording was chosen with this test, so a clean result is a fit and not a score.
"""
import itertools
import pathlib
import sys

from agent_file import load_agent

ASSETS = pathlib.Path(__file__).resolve().parent.parent      # the tutorial's files: one folder up from checks/
WANTED = {
    "ask": [("The dragonfly is flying. It is too far to jump at.", "wait"),
            ("The dragonfly is flying. It is close enough to jump at.", "wait"),
            ("The dragonfly rests. It is too far to jump at.", "creep"),
            ("The dragonfly rests. It is close enough to jump at.", "jump")],
    "agent": [("It is too far to jump at.", "creep"),
              ("It is close enough to jump at.", "jump")],
}


def fit(title, wanted, meanings, set_moves, pick):
    """How many sentences get the wanted move in every order of the moves."""
    right = 0
    for sees, want in wanted:
        picks = []
        for order in itertools.permutations(meanings):
            set_moves({move: meanings[move] for move in order})     # the same moves, in another order
            picks.append(pick(sees))
        good = all(one == want for one in picks)
        right += good
        print(f"{'ok' if good else 'XX'}  want {want:5}  got {'/'.join(picks):36}  {sees}")
    print(f"{title}: right in every order in {right} of {len(wanted)} situations\n")
    return right == len(wanted)


def main():
    sys.path.insert(0, str(ASSETS))
    import ask
    address = sys.argv[1] if len(sys.argv) > 1 else None
    if address:
        ask.MODEL = address

    def set_ask_moves(moves):
        ask.MOVES = moves

    first = fit(f"ask.py, at {ask.MODEL}", WANTED["ask"], dict(ask.MOVES), set_ask_moves,
                lambda sees: ask.ask(sees)["choice"])

    agent, how = load_agent(address=address)
    model = agent["Decider"]("Mapika/decider-2b")

    def set_agent_moves(moves):
        agent["MOVES"] = moves

    second = fit(f"agent.py, the model asked through the {how}", WANTED["agent"], dict(agent["MOVES"]),
                 set_agent_moves, lambda sees: agent["ask"](model, sees))
    return 0 if first and second else 1


if __name__ == "__main__":
    sys.exit(main())
