"""race_many.py - twenty agents ask for one task at the same moment. How many get it?

    python race_many.py

race.py on the page asks twice, one request after the other. This check sends
twenty requests from twenty threads that all start together, and does it five times.
"""
import threading

import requests

import scratch

AGENTS = 20
ROUNDS = 5


def main():
    made, boss = scratch.company("Check race")
    agents = [scratch.idle_agent(made, boss, f"Agent {number}") for number in range(AGENTS)]
    for round_number in range(1, ROUNDS + 1):
        task = scratch.send("POST", "/companies/" + made["id"] + "/issues",
                            {"title": f"One task {round_number}", "status": "todo"})
        answers = []
        together = threading.Barrier(AGENTS)

        def ask(agent):
            together.wait()                  # every thread leaves this line at once
            reply = requests.post(scratch.API + "/issues/" + task["id"] + "/checkout",
                                  json={"agentId": agent["id"], "expectedStatuses": ["todo"]})
            answers.append(reply.status_code)

        threads = [threading.Thread(target=ask, args=(agent,)) for agent in agents]
        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()
        counts = {code: answers.count(code) for code in sorted(set(answers))}
        print(f"Round {round_number}: {AGENTS} requests at once. Answers: {counts}")
    scratch.remove(made)


if __name__ == "__main__":
    main()
