"""your_turn.py - make every "Your turn" change of krueng.ai/decider.html, and run it.

    python your_turn.py                 # all of them, one after the other
    python your_turn.py choice compare  # only these

Each change is made to a copy of the page's file, the way a reader would make it,
and the copy is run. No file on disk is changed. When all of them are run, what
they printed goes to your_turn_output.txt beside this file.
"""
import os
import subprocess
import sys
from pathlib import Path

HERE = Path(__file__).resolve().parent

MESSAGE = '''\
MESSAGE = ("The air conditioner in room 12 has been dripping water onto the bed "
           "since last night. Please send someone before 2 pm. I fly home tomorrow.")'''
LEGEND = '''"legend": ["it can wait a few days", "it should be done today",
                   "it must be done within a few hours"],'''
NUMBERED = '''"legend": {"0": "it can wait a few days",
                   "5": "it should be done today",
                   "10": "it must be done within a few hours"},'''
URGENT = '''    "urgent": {
        "type": "score",
        "instructions": "How soon does the guesthouse have to act?",
        "criteria": ["It can wait a few days", "It should be done today",
                     "It must be done within a few hours"],
    },
'''
LAST_LINE = "print(decider.systemone.__doc__)"

# the change's name: (the file, what it is, [(the text to find, the text to put)])
CHANGES = {
    "first": ("first.py", "another message: two more towels",
              [(MESSAGE, 'MESSAGE = "Can we have two more towels, please?"')]),
    "by_hand_1": ("by_hand.py", "TEMPERATURE = 1",
                  [("TEMPERATURE = 1.164", "TEMPERATURE = 1")]),
    "by_hand_2": ("by_hand.py", "TEMPERATURE = 0.1",
                  [("TEMPERATURE = 1.164", "TEMPERATURE = 0.1")]),
    "choice": ("choice.py", "no meanings: every option is None",
               [('"housekeeping": "Cleaning, towels, bed linen"', '"housekeeping": None'),
                ('"maintenance": "Repairs: air conditioner, water, electricity"',
                 '"maintenance": None'),
                ('"front_desk": "Bookings, check-out, bills, questions"',
                 '"front_desk": None')]),
    "noul": ("noul.py", "the guest also asks for money back",
             [('I fly home tomorrow.")',
               'I fly home tomorrow. I want my money back for last night.")')]),
    "score": ("score.py", "another message: a late check-out next Friday",
              [(MESSAGE, 'MESSAGE = "Could we have a late check-out next Friday?"')]),
    "one_call": ("one_call.py", "the urgent question is taken out", [(URGENT, "")]),
    "look_inside": ("look_inside.py", "one more line: the signature of the class",
                    [(LAST_LINE, LAST_LINE + "\nprint(inspect.signature(Decider))")]),
    "fields": ("fields.py", "the legend as a map with the numbers 0, 5 and 10",
               [(LEGEND, NUMBERED)]),
    "many": ("many.py", "abstain_below=0.9",
             [("abstain_below=0.7", "abstain_below=0.9")]),
    "compare": ("compare.py", "BANK = 5.0", [("BANK = 3.7", "BANK = 5.0")]),
    "too_much": ("too_much.py", "a rule about breakfast in place of the refund rule",
                 [('POLICY = "A night in a room that cannot be slept in is refunded."',
                   'POLICY = "Breakfast is served from 7 to 10 in the morning."')]),
    "long_text": ("long_text.py", "50 rules in place of 150",
                  [("range(1, 151)", "range(1, 51)")]),
}


def changed(name, swaps):
    """A page file's text with the change made. Each text to find must be there once."""
    source = (HERE / name).read_text(encoding="utf-8")
    for find, put in swaps:
        found = source.count(find)
        if found != 1:
            raise SystemExit(f"{name}: expected this text once, found {found}:\n{find}")
        source = source.replace(find, put)
    return source


def run(source):
    """Run Python source as a program. Returns what it printed, or its error."""
    done = subprocess.run([sys.executable, "-"], input=source.encode("utf-8"), cwd=HERE,
                          capture_output=True, env=dict(os.environ, PYTHONUTF8="1"))
    if done.returncode != 0:
        return "FAILED\n" + done.stderr.decode("utf-8", "replace")[-1500:]
    return done.stdout.decode("utf-8").replace("\r\n", "\n")


def main():
    wanted = sys.argv[1:] or list(CHANGES)
    report = []
    for key in wanted:
        name, what, swaps = CHANGES[key]
        printed = run(changed(name, swaps)).rstrip()
        report.append(f"=== {key}  {name}: {what}\n{printed}\n")
        print(report[-1], flush=True)
    if wanted == list(CHANGES):
        output = HERE / "your_turn_output.txt"
        output.write_text("\n".join(report), encoding="utf-8", newline="\n")
        print("wrote", output.name)
    return 1 if any("FAILED" in part for part in report) else 0


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