def get_game_history(self, request):
        """Get player game history."""
        player = User.query(User.name == request.player).get()
        if not player:
            raise endpoints.NotFoundException(
                '{0} does not exist!'.format(request.player)
            )

        games = Game.query(
            ndb.AND(
                Game.game_over == True,  # noqa
                ndb.OR(
                    Game.player_one == player.key,
                    Game.player_two == player.key
                )
            )
        )

        game_histories = []
        for game in games:
            player_one = game.player_one.get()
            player_two = game.player_two.get()

            if game.is_forfeit:
                game_histories.append(
                    GameHistoryForm(
                        game_urlsafe_key=game.key.urlsafe(),
                        player_one=player_one.name,
                        player_two=player_two.name,
                        is_forfeit=game.is_forfeit,
                        winner=game.winner.get().name
                    )
                )
            else:
                p1_hands = Hand.query(
                    Hand.game == game.key,
                    Hand.player == player_one.key
                )
                p1_hands = Poker.get_player_start_end_hands(p1_hands)
                p2_hands = Hand.query(
                    Hand.game == game.key,
                    Hand.player == player_two.key
                )
                p2_hands = Poker.get_player_start_end_hands(p2_hands)
                game_histories.append(
                    GameHistoryForm(
                        game_urlsafe_key=game.key.urlsafe(),
                        player_one=player_one.name,
                        player_one_start_hand=repr(p1_hands[0]),
                        player_one_end_hand=repr(p1_hands[1]),
                        player_two=player_two.name,
                        player_two_start_hand=repr(p2_hands[0]),
                        player_two_end_hand=repr(p2_hands[1]),
                        is_forfeit=game.is_forfeit,
                        winner=game.winner.get().name
                    )
                )
        return GameHistoryForms(
            games=game_histories
        )
    def make_move(game, player, card_ids):
        """Record and respond to player's move.

        Record player card exchanges if any requeted. An empty card_ids means
        the player does not want to exchange any of his/her cards.

        Args:
          game: An entity representing the game state.
          player: An entity representing the active player.
          card_ids: A list with the cards the player wants to exchange.

        Returns:
          The player's final hand.

        Raises:
          ForbiddenException: Player is trying to exchange more than the
            max hand size; 5 cards.
        """
        final_hand = Hand.query(
            ndb.AND(Hand.game == game.key, Hand.player == player.key)
        ).get()
        final_hand = Poker.load_player_hand(final_hand.hand)
        deck = Deck.construct_json_deck(game.deck)

        if len(card_ids) > 0:
            if len(card_ids) < 6:
                final_hand = Poker.get_new_cards(deck, final_hand, card_ids)
            else:
                raise endpoints.ForbiddenException(
                    '''It is not possible to exchange more cards than your hand
                     size'''
                )

        if game.active_player == game.player_one:
            Poker.save_turn_one_game_state(game, deck, final_hand)
        else:
            player_one_hand = Hand.query(
                ndb.AND(Hand.game == game.key, Hand.player == game.player_one)
            ).get()
            player_one_hand = Poker.load_player_hand(player_one_hand.hand)
            Poker.save_turn_two_game_state(
                game,
                deck,
                final_hand,
                player_one_hand
            )
            Poker.update_player_stats(game)

        return final_hand
    def post(self):
        """Send an email to a User that it is their turn."""
        user = get_by_urlsafe(self.request.get('user_key'), User)
        game = get_by_urlsafe(self.request.get('game_key'), Game)

        player_hand = Hand.query(
            ndb.AND(
                Hand.player == user.key,
                Hand.game == game.key,
                Hand.state == HandState.STARTING.name
            )
        ).get()

        if not player_hand:
            raise endpoints.NotFoundException(
                'Hand not found for player key {0} and game key {1}'.format(
                    user.key, game.key
                )
            )

        hand = json.loads(player_hand.hand)
        cards = [Card(name=card['name'], suit=card['suit']) for card in hand]
        hand_information = ''
        for card in cards:
            hand_information += 'Card: {0}\nCard Id: {1}\n\n'.format(
                repr(card),
                card.id
            )

        subject = 'Your Turn!'
        body = '''
Hi {0}!

It's your turn current turn to play five card poker! Choose the cards you want
to replace, if any, and respond to us. After your move, we will reveal your new
hand. After each player makes their move, the game will notify each player the
winner by email. May the player with the best hand win!

The game key is:
{2}

Here is your hand:
{1}

Notice, below each listed card is a "Card Id"; this is what you will use to
identify to the server which cards you want to exchange when you make your next
move to the server.
        '''.format(user.name, hand_information, game.key.urlsafe())

        print body
        mail.send_mail(
            'noreply@{}.appspotmail.com'.format(
                app_identity.get_application_id()
            ),
            user.email,
            subject,
            body
        )
    def get_user_hand(self, request):
        """Get player's most recent hand state for a given game."""
        game = get_by_urlsafe(request.game_urlsafe_key, Game)
        player = User.query(User.name == request.player).get()
        if not player:
            raise endpoints.NotFoundException(
                '{0} does not exist!'.format(request.player)
            )
        if game.player_one != player.key and game.player_two != player.key:
            raise endpoints.ForbiddenException(
                '{0} is not part of this game!'.format(request.player)
            )

        def get_card_form(hand):
            card_forms = []
            hand = Poker.load_player_hand(hand.hand)
            for card in hand:
                card_forms.append(
                    CardForm(name=card.name, suit=card.suit, card_id=card.id)
                )
            return card_forms

        cards = []
        state = 'STARTING'
        hands = Hand.query(
            Hand.game == game.key, Hand.player == player.key
        ).fetch()

        if len(hands) == 1:
            cards = get_card_form(hands[0])
        else:
            state = 'ENDING'
            for hand in hands:
                if hand.state == HandState.ENDING.name:
                    cards = get_card_form(hand)

        return PlayerHandForm(
            name=player.name,
            cards=cards,
            state=state
        )
    def post(self):
        """Send an email to the players to notify them the game results."""
        game = get_by_urlsafe(self.request.get('game_key'), Game)

        player_one_hand = Hand.query(
            ndb.AND(
                Hand.player == game.player_one,
                Hand.game == game.key,
                Hand.state == HandState.ENDING.name
            )
        ).get()
        if not player_one_hand:
            raise endpoints.NotFoundException(
                'Hand not found for player key {0} and game key {1}'.format(
                    game.player_one, game.key
                )
            )

        player_two_hand = Hand.query(
            ndb.AND(
                Hand.player == game.player_two,
                Hand.game == game.key,
                Hand.state == HandState.ENDING.name
            )
        ).get()
        if not player_two_hand:
            raise endpoints.NotFoundException(
                'Hand not found for player key {0} and game key {1}'.format(
                    game.player_two, game.key
                )
            )

        player_one = game.player_one.get()
        hand = json.loads(player_one_hand.hand)
        cards = [Card(name=card['name'], suit=card['suit']) for card in hand]
        p1_hand_information = ''
        for card in cards:
            p1_hand_information += 'Card: {0}\n'.format(repr(card))

        player_two = game.player_two.get()
        hand = json.loads(player_two_hand.hand)
        cards = [Card(name=card['name'], suit=card['suit']) for card in hand]
        p2_hand_information = ''
        for card in cards:
            p2_hand_information += 'Card: {0}\n'.format(repr(card))

        subject = 'It''s a tie!'
        if game.winner == game.player_one:
            subject = '{0} Wins'.format(player_one.name)
        elif game.winner == game.player_two:
            subject = '{0} Wins!'.format(player_two.name)

        body = '''
Game finished! {0}

{1}'s hand:
{2}

{3}'s hand:
{4}
        '''.format(
            subject,
            player_one.name,
            p1_hand_information,
            player_two.name,
            p2_hand_information
        )

        print body
        mail.send_mail(
            'noreply@{}.appspotmail.com'.format(
                app_identity.get_application_id()
            ),
            player_one.email,
            subject,
            body
        )
        mail.send_mail(
            'noreply@{}.appspotmail.com'.format(
                app_identity.get_application_id()
            ),
            player_two.email,
            subject,
            body
        )