# Path: foosball/games/models.py
# class Game(TimeStampedModel):
#     created_by = models.ForeignKey(
#         User, related_name="games_created", editable=False, null=True, verbose_name=_("created by")
#     )
#     modified_by = models.ForeignKey(
#         User, related_name="games_modified", editable=False, null=True, verbose_name=_("modified by")
#     )
# 
#     played_at = models.DateTimeField(
#         default=timezone.now,
#         verbose_name=_("played at"),
#         help_text=_("Time when the game was played")
#     )
# 
#     table = models.ForeignKey(Table, blank=True, null=True, related_name="games", verbose_name=_("table"))
# 
#     class Meta:
#         ordering = ['-played_at']
# 
#     def __str__(self):
#         return " - ".join(map(str, self.teams.all()))
# 
# class Team(models.Model):
#     UNKNOWN = 0
#     RED = 1
#     BLUE = 2
#     SIDE_CHOICES = (
#         (UNKNOWN, _("Unknown")),
#         (RED, _("Red")),
#         (BLUE, _("Blue")),
#     )
#     side = models.IntegerField(db_index=True, choices=SIDE_CHOICES, default=UNKNOWN, verbose_name=_("side"))
# 
#     game = models.ForeignKey(Game, related_name="teams", on_delete=models.CASCADE)
#     score = models.PositiveSmallIntegerField(
#         verbose_name=_("score"),
#         help_text=_("Team's score in the game"),
#         validators=[MaxValueValidator(limit_value=10)]
#     )
#     players = models.ManyToManyField(User)
# 
#     def __str__(self):
#         return "%s (%s)" % (
#             self.score,
#             ", ".join(map(str, self.players.all()))
#         )
# 
# Path: foosball/games/stats.py
# def update_player_stats(instance):
#     """
#     Update player win and played counts for players of a Team.
# 
#     :param instance: Team that will be used to update players.
#     :type instance: Team
#     """
#     for user in instance.players.all():
#         totals = {1: 0, 2: 0}
#         wins = {1: 0, 2: 0}
#         teams = Team.objects.filter(players__id=user.id).prefetch_related("players")
#         for team in teams:
#             player_count = len(team.players.all())
#             totals[player_count] += 1
#             if team.score == 10:
#                 wins[player_count] += 1
#         player, _created = Player.objects.get_or_create(user=user)
#         player.singles_wins = wins[1]
#         player.doubles_wins = wins[2]
#         player.singles_played = totals[1]
#         player.doubles_played = totals[2]
#         if totals[1]:
#             player.singles_win_percentage = round((wins[1]/totals[1])*100, 2)
#         else:
#             player.singles_win_percentage = 0
#         if totals[2]:
#             player.doubles_win_percentage = round((wins[2] / totals[2])*100, 2)
#         else:
#             player.doubles_win_percentage = 0
#         player.total_played = totals[1] + totals[2]
#         player.save()
# 
# Path: foosball/games/tests/factories.py
# class TeamFactory(factory.django.DjangoModelFactory):
#     score = factory.fuzzy.FuzzyInteger(10)
# 
#     @factory.post_generation
#     def players(self, create, extracted, **kwargs):
#         if not create:
#             # Simple build, do nothing.
#             return
# 
#         if extracted:
#             # A list of players was passed in, use them
#             for player in extracted:
#                 self.players.add(player)
#             return
# 
#         self.players.add(UserFactory())
#         self.players.add(UserFactory())
# 
#     class Meta:
#         model = 'games.Team'


from foosball.games.models import Game, Team
from foosball.games.stats import update_player_stats
from foosball.games.tests.factories import TeamFactory
from foosball.users.tests.factories import UserFactory


def handle_login(client):
    """
    Create user and log the user in.
    """
    user = UserFactory(username="foobar")
    client.force_login(user)


def create_game(winner_loser=("RED", "BLUE"), players=(None, None)):
    """
    Create a game and teams.

    Optionally with given winner/loser sides and players passed in as tuples.
    """
    game = Game.objects.create()
    winners = TeamFactory(score=10, game=game, side=getattr(Team, winner_loser[0]), players=players[0])
    update_player_stats(winners)
    losers = TeamFactory(score=5, game=game, side=getattr(Team, winner_loser[1]), players=players[1])

# Path: foosball/games/models.py
# class Game(TimeStampedModel):
#     created_by = models.ForeignKey(
#         User, related_name="games_created", editable=False, null=True, verbose_name=_("created by")
#     )
#     modified_by = models.ForeignKey(
#         User, related_name="games_modified", editable=False, null=True, verbose_name=_("modified by")
#     )
# 
#     played_at = models.DateTimeField(
#         default=timezone.now,
#         verbose_name=_("played at"),
#         help_text=_("Time when the game was played")
#     )
# 
#     table = models.ForeignKey(Table, blank=True, null=True, related_name="games", verbose_name=_("table"))
# 
#     class Meta:
#         ordering = ['-played_at']
# 
#     def __str__(self):
#         return " - ".join(map(str, self.teams.all()))
# 
# class Team(models.Model):
#     UNKNOWN = 0
#     RED = 1
#     BLUE = 2
#     SIDE_CHOICES = (
#         (UNKNOWN, _("Unknown")),
#         (RED, _("Red")),
#         (BLUE, _("Blue")),
#     )
#     side = models.IntegerField(db_index=True, choices=SIDE_CHOICES, default=UNKNOWN, verbose_name=_("side"))
# 
#     game = models.ForeignKey(Game, related_name="teams", on_delete=models.CASCADE)
#     score = models.PositiveSmallIntegerField(
#         verbose_name=_("score"),
#         help_text=_("Team's score in the game"),
#         validators=[MaxValueValidator(limit_value=10)]
#     )
#     players = models.ManyToManyField(User)
# 
#     def __str__(self):
#         return "%s (%s)" % (
#             self.score,
#             ", ".join(map(str, self.players.all()))
#         )
# 
# Path: foosball/games/stats.py
# def update_player_stats(instance):
#     """
#     Update player win and played counts for players of a Team.
# 
#     :param instance: Team that will be used to update players.
#     :type instance: Team
#     """
#     for user in instance.players.all():
#         totals = {1: 0, 2: 0}
#         wins = {1: 0, 2: 0}
#         teams = Team.objects.filter(players__id=user.id).prefetch_related("players")
#         for team in teams:
#             player_count = len(team.players.all())
#             totals[player_count] += 1
#             if team.score == 10:
#                 wins[player_count] += 1
#         player, _created = Player.objects.get_or_create(user=user)
#         player.singles_wins = wins[1]
#         player.doubles_wins = wins[2]
#         player.singles_played = totals[1]
#         player.doubles_played = totals[2]
#         if totals[1]:
#             player.singles_win_percentage = round((wins[1]/totals[1])*100, 2)
#         else:
#             player.singles_win_percentage = 0
#         if totals[2]:
#             player.doubles_win_percentage = round((wins[2] / totals[2])*100, 2)
#         else:
#             player.doubles_win_percentage = 0
#         player.total_played = totals[1] + totals[2]
#         player.save()
# 
# Path: foosball/games/tests/factories.py
# class TeamFactory(factory.django.DjangoModelFactory):
#     score = factory.fuzzy.FuzzyInteger(10)
# 
#     @factory.post_generation
#     def players(self, create, extracted, **kwargs):
#         if not create:
#             # Simple build, do nothing.
#             return
# 
#         if extracted:
#             # A list of players was passed in, use them
#             for player in extracted:
#                 self.players.add(player)
#             return
# 
#         self.players.add(UserFactory())
#         self.players.add(UserFactory())
# 
#     class Meta:
#         model = 'games.Team'


# Path: foosball/games/tests/utils.py
from foosball.games.models import Game, Team
from foosball.games.stats import update_player_stats
from foosball.games.tests.factories import TeamFactory
from foosball.users.tests.factories import UserFactory



def handle_login(client):
    """
    Create user and log the user in.
    """
    user = UserFactory(username="foobar")
    client.force_login(user)


def create_game(winner_loser=("RED", "BLUE"), players=(None, None)):
    """
    Create a game and teams.

    Optionally with given winner/loser sides and players passed in as tuples.
    """
    game = Game.objects.create()
    winners = TeamFactory(score=10, game=game, side=getattr(Team, winner_loser[0]), players=players[0])
    update_player_stats(winners)
    losers = TeamFactory(score=5, game=game, side=getattr(Team, winner_loser[1]), players=players[1])

    update_player_stats(losers)