package org.luxons.sevenwonders.game;

import java.util.Collection;
import java.util.List;

import org.junit.Test;
import org.luxons.sevenwonders.game.api.CustomizableSettings;
import org.luxons.sevenwonders.game.api.HandCard;
import org.luxons.sevenwonders.game.api.PlayerMove;
import org.luxons.sevenwonders.game.api.PlayerTurnInfo;
import org.luxons.sevenwonders.game.cards.Card;
import org.luxons.sevenwonders.game.data.GameDefinitionLoader;
import org.luxons.sevenwonders.game.moves.MoveType;
import org.luxons.sevenwonders.game.test.TestUtils;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class GameTest {

    @Test
    public void testFullGame() {
        int nbPlayers = 5;
        Game game = createGame(nbPlayers);

        for (int age = 1; age <= 3; age++) {
            playAge(nbPlayers, game, age);
        }
    }

    private void playAge(int nbPlayers, Game game, int age) {
        for (int i = 0; i < 6; i++) {
            playTurn(nbPlayers, game, age, 7 - i);
        }
    }

    private static Game createGame(int nbPlayers) {
        CustomizableSettings settings = TestUtils.createCustomizableSettings();
        return new GameDefinitionLoader().getGameDefinition().initGame(0, settings, nbPlayers);
    }

    private static void playTurn(int nbPlayers, Game game, int ageToCheck, int handSize) {
        Collection<PlayerTurnInfo> turnInfos = game.getCurrentTurnInfo();
        assertEquals(nbPlayers, turnInfos.size());
        for (PlayerTurnInfo turnInfo : turnInfos) {
            assertEquals(ageToCheck, turnInfo.getCurrentAge());
            assertEquals(handSize, turnInfo.getHand().size());
            PlayerMove move = getFirstAvailableMove(turnInfo);
            if (move != null) {
                game.prepareMove(turnInfo.getPlayerIndex(), move);
            }
        }
        assertTrue(game.allPlayersPreparedTheirMove());
        game.playTurn();
    }

    private static PlayerMove getFirstAvailableMove(PlayerTurnInfo turnInfo) {
        switch (turnInfo.getAction()) {
        case PLAY:
        case PLAY_2:
        case PLAY_LAST:
            return createPlayCardMove(turnInfo);
        case PICK_NEIGHBOR_GUILD:
            return createPickGuildMove(turnInfo);
        case WAIT:
        default:
            return null;
        }
    }

    private static PlayerMove createPlayCardMove(PlayerTurnInfo turnInfo) {
        for (HandCard handCard : turnInfo.getHand()) {
            if (handCard.isFree()) {
                return createMove(handCard, MoveType.PLAY);
            }
        }
        return createMove(turnInfo.getHand().get(0), MoveType.DISCARD);
    }

    private static PlayerMove createPickGuildMove(PlayerTurnInfo turnInfo) {
        List<Card> neighbourGuilds = turnInfo.getNeighbourGuildCards();
        assertNotNull(neighbourGuilds);
        String cardName = neighbourGuilds.isEmpty() ? null : neighbourGuilds.get(0).getName();
        PlayerMove move = new PlayerMove();
        move.setCardName(cardName);
        move.setType(MoveType.COPY_GUILD);
        return move;
    }

    private static PlayerMove createMove(HandCard handCard, MoveType type) {
        PlayerMove move = new PlayerMove();
        move.setCardName(handCard.getCard().getName());
        move.setType(type);
        return move;
    }
}

@@ -78,20 +78,68 @@
 va.util.
-List
+HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0Aimpor
@@ -376,16 +376,63 @@
 rnInfo;%0A
+import org.luxons.sevenwonders.game.api.Table;%0A
 import o
@@ -534,16 +534,64 @@
 Loader;%0A
+import org.luxons.sevenwonders.game.moves.Move;%0A
 import o
@@ -778,16 +778,59 @@
 otNull;%0A
+import static org.junit.Assert.assertSame;%0A
 import s
@@ -1719,32 +1719,111 @@
 rnInfos.size());
+%0A%0A        Map%3CInteger, PlayerMove%3E sentMoves = new HashMap%3C%3E(turnInfos.size());
 %0A        for (Pl
@@ -2144,24 +2144,88 @@
 x(), move);%0A
+                sentMoves.put(turnInfo.getPlayerIndex(), move);%0A
             
@@ -2295,24 +2295,38 @@
 ());%0A       
+ Table table =
  game.playTu
@@ -2327,24 +2327,528 @@
 playTurn();%0A
+        checkLastPlayedMoves(sentMoves, table);%0A    %7D%0A%0A    private static void checkLastPlayedMoves(Map%3CInteger, PlayerMove%3E sentMoves, Table table) %7B%0A        for (Move move : table.getLastPlayedMoves()) %7B%0A            PlayerMove sentMove = sentMoves.get(move.getPlayerIndex());%0A            assertNotNull(sentMove);%0A            assertNotNull(move.getCard());%0A            assertEquals(sentMove.getCardName(), move.getCard().getName());%0A            assertSame(sentMove.getType(), move.getType());%0A        %7D%0A
     %7D%0A%0A    p

Add checks on last played moves in GameTest