package org.amc.game.chessserver;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.amc.game.chess.ChessBoard;
import org.amc.game.chess.ChessBoardUtilities;
import org.amc.game.chess.ChessGame;
import org.amc.game.chess.ChessGameFactory;
import org.amc.game.chess.ChessGameFixture;
import org.amc.game.chess.ChessGamePlayer;
import org.amc.game.chess.ComparePlayers;
import org.amc.game.chess.IllegalMoveException;
import org.amc.game.chess.Move;
import org.amc.game.chess.Player;
import org.amc.game.chess.AbstractChessGame.GameState;
import org.amc.game.chessserver.AbstractServerChessGame.ServerGameStatus;
import org.junit.Before;
import org.junit.Test;

public class ServerChessGameConstructorTest {
    private ChessGameFactory chessGameFactory;
    private ChessGameFixture fixture;
    private ChessGame mockChessGame;
    
    private static final long UID = 120l;
    private static final long INVALID_UID = 233l;

    @Before
    public void setUp() throws Exception {
        chessGameFactory = new ChessGameFactory() {
            @Override
            public ChessGame getChessGame(ChessBoard board, ChessGamePlayer playerWhite,
                            ChessGamePlayer playerBlack) {
                return new ChessGame(board, playerWhite, playerBlack);
            }
        };
        
        fixture = new ChessGameFixture();
        fixture.initialise();
        mockChessGame = mock(ChessGame.class);
        
    }
        
    private ServerChessGame createServerChessGame(long UID, Player player) {
        ServerChessGame game = new ServerChessGame(UID, player) {

            private static final long serialVersionUID = 1L;

            @Override
            public void addOpponent(Player opponent) {
                // Do nothing
                
            }
        };
        game.setChessGameFactory(chessGameFactory);
        return game;
    }
    
    private ServerChessGame createServerChessGame(long UID, ChessGame chessGame) {
        ServerChessGame game = new ServerChessGame(UID, chessGame) {

            private static final long serialVersionUID = 1L;

            @Override
            public void addOpponent(Player opponent) {
                // Do nothing
                
            }
        };
        game.setChessGameFactory(chessGameFactory);
        return game;
    }
    
    @Test(expected = IllegalArgumentException.class)
    public void testNullPlayerPassedToConstructor() {
    	Player p = null;
    	createServerChessGame(INVALID_UID, p);
    }
    
    @Test(expected = IllegalArgumentException.class)
    public void testNullChessGamePassedToConstructor() {
    	ChessGame c = null;
    	createServerChessGame(INVALID_UID, c);
    }
    
    @Test
    public void constructorTest() {
        ServerChessGame scgGame = new ServerChessGame() {
            
            private static final long serialVersionUID = 1L;
            
            @Override
            public void addOpponent(Player opponent) {
                // do nothing
            }
        };
        
        assertEquals(0L, scgGame.getUid());
        assertNull(scgGame.getChessGame());
        assertNull(scgGame.getPlayer());
        assertNull(scgGame.getOpponent());
        assertEquals(ServerGameStatus.NEW, scgGame.getCurrentStatus());
        assertEquals(0, scgGame.getNoOfObservers());
        assertNull(scgGame.getChessGameFactory());
    }
    
    @Test
    public void constructorChessGameTest() {
        ChessGameFixture fixture = new ChessGameFixture();
        ServerChessGame scgGame = createServerChessGame(UID, fixture.getChessGame());
        
        assertEquals(UID, scgGame.getUid());
        assertNotNull(scgGame.getChessGame());
        assertFalse(scgGame.getChessGame() == fixture.getChessGame());
        assertTrue(ComparePlayers.comparePlayers(fixture.getWhitePlayer(), scgGame.getPlayer()));
        assertTrue(ComparePlayers.comparePlayers(fixture.getBlackPlayer(), scgGame.getOpponent()));
        assertEquals(ServerGameStatus.IN_PROGRESS, scgGame.getCurrentStatus());
        assertEquals(0, scgGame.getNoOfObservers());
        assertNotNull(scgGame.getChessGameFactory());
        
        ChessBoardUtilities.compareBoards(fixture.getChessGame().getChessBoard(), 
                        scgGame.getChessGame().getChessBoard());
    }
    
    @Test
    public void testMove() throws IllegalMoveException {
        
        ServerChessGame scgGame = createServerChessGame(UID, fixture.getChessGame());
        scgGame.setChessGame(mockChessGame);
        when(mockChessGame.getGameState()).thenReturn(GameState.RUNNING);
        
        Move move = new Move("A2-A3");
        scgGame.move(fixture.getCurrentPlayer(), move);
        verify(mockChessGame, times(1)).move(eq(fixture.getWhitePlayer()), eq(move));
        verify(mockChessGame, times(1)).changePlayer();
        verify(mockChessGame, times(2)).getGameState();
    }
    
    @Test
    public void checkStatusInCheckTest() throws IllegalMoveException {
        
        ServerChessGame scgGame = createServerChessGame(UID, fixture.getChessGame());
        scgGame.setChessGame(mockChessGame);
        when(mockChessGame.getGameState()).thenReturn(GameState.BLACK_IN_CHECK);
        
        Move move = new Move("A2-A3");
        scgGame.move(fixture.getCurrentPlayer(), move);
        verify(mockChessGame, times(1)).move(eq(fixture.getWhitePlayer()), eq(move));
        verify(mockChessGame, times(1)).changePlayer();
        verify(mockChessGame, times(3)).getGameState();
    }
    
    @Test
    public void checkStatusStalemateTest() throws IllegalMoveException {
        
        ServerChessGame scgGame = createServerChessGame(UID, fixture.getChessGame());
        scgGame.setChessGame(mockChessGame);
        when(mockChessGame.getGameState()).thenReturn(GameState.STALEMATE);
        
        Move move = new Move("A2-A3");
        scgGame.move(fixture.getCurrentPlayer(), move);
        verify(mockChessGame, times(1)).move(eq(fixture.getWhitePlayer()), eq(move));
        verify(mockChessGame, times(1)).changePlayer();
        verify(mockChessGame, times(2)).getGameState();
        assertEquals(ServerGameStatus.FINISHED, scgGame.getCurrentStatus());
        
    }
    
    @Test
    public void testMoveOnNullChessBoard() throws IllegalMoveException {
        ServerChessGame scgGame = createServerChessGame(UID, fixture.getChessGame());
        scgGame.setChessGame(null);
        
        Move move = new Move("A2-A3");
        scgGame.move(fixture.getCurrentPlayer(), move);
        
        verify(mockChessGame, times(0)).move(eq(fixture.getWhitePlayer()), eq(move));
        verify(mockChessGame, times(0)).changePlayer();
        verify(mockChessGame, times(0)).getGameState();
    }
}

@@ -142,55 +142,8 @@
 rd;%0A
-import org.amc.game.chess.ChessBoardUtilities;%0A
 impo
@@ -310,50 +310,8 @@
 er;%0A
-import org.amc.game.chess.ComparePlayers;%0A
 impo
@@ -2664,1624 +2664,8 @@
 est%0A
-    public void constructorTest() %7B%0A        ServerChessGame scgGame = new ServerChessGame() %7B%0A            %0A            private static final long serialVersionUID = 1L;%0A            %0A            @Override%0A            public void addOpponent(Player opponent) %7B%0A                // do nothing%0A            %7D%0A        %7D;%0A        %0A        assertEquals(0L, scgGame.getUid());%0A        assertNull(scgGame.getChessGame());%0A        assertNull(scgGame.getPlayer());%0A        assertNull(scgGame.getOpponent());%0A        assertEquals(ServerGameStatus.NEW, scgGame.getCurrentStatus());%0A        assertEquals(0, scgGame.getNoOfObservers());%0A        assertNull(scgGame.getChessGameFactory());%0A    %7D%0A    %0A    @Test%0A    public void constructorChessGameTest() %7B%0A        ChessGameFixture fixture = new ChessGameFixture();%0A        ServerChessGame scgGame = createServerChessGame(UID, fixture.getChessGame());%0A        %0A        assertEquals(UID, scgGame.getUid());%0A        assertNotNull(scgGame.getChessGame());%0A        assertFalse(scgGame.getChessGame() == fixture.getChessGame());%0A        assertTrue(ComparePlayers.comparePlayers(fixture.getWhitePlayer(), scgGame.getPlayer()));%0A        assertTrue(ComparePlayers.comparePlayers(fixture.getBlackPlayer(), scgGame.getOpponent()));%0A        assertEquals(ServerGameStatus.IN_PROGRESS, scgGame.getCurrentStatus());%0A        assertEquals(0, scgGame.getNoOfObservers());%0A        assertNotNull(scgGame.getChessGameFactory());%0A        %0A        ChessBoardUtilities.compareBoards(fixture.getChessGame().getChessBoard(), %0A                        scgGame.getChessGame().getChessBoard());%0A    %7D%0A    %0A    @Test%0A
     

remove duplicate code fro /ServerChessGameConstructorTest which is in AbstractServerChessGameTest"